- /// Encode the given value or a previously cached shorthand.
- fn encode_with_shorthand<T, U, M>(&mut self,
- value: &T,
- variant: &U,
- map: M)
- -> Result<(), <Self as Encoder>::Error>
- where M: for<'b> Fn(&'b mut Self) -> &'b mut FxHashMap<T, usize>,
- T: Clone + Eq + Hash,
- U: Encodable
- {
- let existing_shorthand = map(self).get(value).cloned();
- if let Some(shorthand) = existing_shorthand {
- return self.emit_usize(shorthand);
- }
-
- let start = self.position();
- variant.encode(self)?;
- let len = self.position() - start;
-
- // The shorthand encoding uses the same usize as the
- // discriminant, with an offset so they can't conflict.
- let discriminant = unsafe { intrinsics::discriminant_value(variant) };
- assert!(discriminant < SHORTHAND_OFFSET as u64);
- let shorthand = start + SHORTHAND_OFFSET;
-
- // Get the number of bits that leb128 could fit
- // in the same space as the fully encoded type.
- let leb128_bits = len * 7;
-
- // Check that the shorthand is a not longer than the
- // full encoding itself, i.e. it's an obvious win.
- if leb128_bits >= 64 || (shorthand as u64) < (1 << leb128_bits) {
- map(self).insert(value.clone(), shorthand);
- }
-
- Ok(())
- }
-