diff options
Diffstat (limited to 'vendor/zerovec-derive/examples/derives.rs')
-rw-r--r-- | vendor/zerovec-derive/examples/derives.rs | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/vendor/zerovec-derive/examples/derives.rs b/vendor/zerovec-derive/examples/derives.rs new file mode 100644 index 000000000..40f821023 --- /dev/null +++ b/vendor/zerovec-derive/examples/derives.rs @@ -0,0 +1,157 @@ +// This file is part of ICU4X. For terms of use, please see the file +// called LICENSE at the top level of the ICU4X source tree +// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). + +use zerovec::ule::AsULE; +use zerovec::ule::EncodeAsVarULE; +use zerovec::*; + +#[repr(packed)] +#[derive(ule::ULE, Copy, Clone)] +pub struct FooULE { + a: u8, + b: <u32 as AsULE>::ULE, + c: <char as AsULE>::ULE, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +struct Foo { + a: u8, + b: u32, + c: char, +} + +impl AsULE for Foo { + type ULE = FooULE; + fn to_unaligned(self) -> FooULE { + FooULE { + a: self.a, + b: self.b.to_unaligned(), + c: self.c.to_unaligned(), + } + } + + fn from_unaligned(other: FooULE) -> Self { + Self { + a: other.a, + b: AsULE::from_unaligned(other.b), + c: AsULE::from_unaligned(other.c), + } + } +} + +#[repr(packed)] +#[derive(ule::VarULE)] +pub struct RelationULE { + /// This maps to (AndOr, Polarity, Operand), + /// with the first bit mapping to AndOr (1 == And), the second bit + /// to Polarity (1 == Positive), and the remaining bits to Operand + /// encoded via Operand::encode. It is unsound for the Operand bits to + /// not be a valid encoded Operand. + andor_polarity_operand: u8, + modulo: <u32 as AsULE>::ULE, + range_list: ZeroSlice<Foo>, +} + +#[derive(Clone, PartialEq, Debug)] +pub struct Relation<'a> { + andor_polarity_operand: u8, + modulo: u32, + range_list: ZeroVec<'a, Foo>, +} + +unsafe impl EncodeAsVarULE<RelationULE> for Relation<'_> { + fn encode_var_ule_as_slices<R>(&self, cb: impl FnOnce(&[&[u8]]) -> R) -> R { + cb(&[ + &[self.andor_polarity_operand], + ule::ULE::as_byte_slice(&[self.modulo.to_unaligned()]), + self.range_list.as_bytes(), + ]) + } +} + +impl RelationULE { + pub fn as_relation(&self) -> Relation { + Relation { + andor_polarity_operand: self.andor_polarity_operand, + modulo: u32::from_unaligned(self.modulo), + range_list: self.range_list.as_zerovec(), + } + } +} + +const TEST_SLICE: &[Foo] = &[ + Foo { + a: 101, + b: 924, + c: '⸘', + }, + Foo { + a: 217, + b: 4228, + c: 'ə', + }, + Foo { + a: 117, + b: 9090, + c: 'ø', + }, +]; + +const TEST_SLICE2: &[Foo] = &[ + Foo { + a: 92, + b: 4, + c: 'å', + }, + Foo { + a: 9, + b: 49993, + c: '±', + }, +]; +fn test_zerovec() { + let zerovec: ZeroVec<Foo> = TEST_SLICE.iter().copied().collect(); + + assert_eq!(zerovec, TEST_SLICE); + + let bytes = zerovec.as_bytes(); + let reparsed: ZeroVec<Foo> = ZeroVec::parse_byte_slice(bytes).expect("Parsing should succeed"); + + assert_eq!(reparsed, TEST_SLICE); +} + +fn test_varzerovec() { + let relation1 = Relation { + andor_polarity_operand: 1, + modulo: 5004, + range_list: TEST_SLICE.iter().copied().collect(), + }; + let relation2 = Relation { + andor_polarity_operand: 5, + modulo: 909, + range_list: TEST_SLICE2.iter().copied().collect(), + }; + + let relations = &[relation1, relation2]; + + let vzv = VarZeroVec::<_>::from(relations); + + for (ule, stack) in vzv.iter().zip(relations.iter()) { + assert_eq!(*stack, ule.as_relation()); + } + + let bytes = vzv.as_bytes(); + + let recovered: VarZeroVec<RelationULE> = + VarZeroVec::parse_byte_slice(bytes).expect("Parsing should succeed"); + + for (ule, stack) in recovered.iter().zip(relations.iter()) { + assert_eq!(*stack, ule.as_relation()); + } +} + +fn main() { + test_zerovec(); + test_varzerovec(); +} |