summaryrefslogtreecommitdiffstats
path: root/vendor/zerovec-derive/examples/derives.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/zerovec-derive/examples/derives.rs')
-rw-r--r--vendor/zerovec-derive/examples/derives.rs157
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();
+}