//! ULE impls for tuples. //! //! Rust does not guarantee the layout of tuples, so ZeroVec defines its own tuple ULE types. //! //! Impls are defined for tuples of up to 6 elements. For longer tuples, use a custom struct //! with [`#[make_ule]`](crate::make_ule). //! //! # Examples //! //! ``` //! use zerovec::ZeroVec; //! //! // ZeroVec of tuples! //! let zerovec: ZeroVec<(u32, char)> = [(1, 'a'), (1234901, '啊'), (100, 'अ')] //! .iter() //! .copied() //! .collect(); //! //! assert_eq!(zerovec.get(1), Some((1234901, '啊'))); //! ```
usesuper::*; use core::fmt; use core::mem;
macro_rules! tuple_ule {
($name:ident, $len:literal, [ $($t:ident $i:tt),+ ]) => { #[doc = concat!("ULE type for tuples with ", $len, " elements.")] #[repr(C, packed)] #[allow(clippy::exhaustive_structs)] // stable pubstruct $name<$($t),+>($(pub $t),+);
// Safety (based on the safety checklist on the ULE trait): // 1. TupleULE does not include any uninitialized or padding bytes. // (achieved by `#[repr(C, packed)]` on a struct containing only ULE fields) // 2. TupleULE is aligned to 1 byte. // (achieved by `#[repr(C, packed)]` on a struct containing only ULE fields) // 3. The impl of validate_byte_slice() returns an error if any byte is not valid. // 4. The impl of validate_byte_slice() returns an error if there are extra bytes. // 5. The other ULE methods use the default impl. // 6. TupleULE byte equality is semantic equality by relying on the ULE equality // invariant on the subfields unsafeimpl<$($t: ULE),+> ULE for $name<$($t),+> { fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError> { // expands to: 0size + mem::size_of::<A>() + mem::size_of::<B>(); let ule_bytes = 0usize $(+ mem::size_of::<$t>())+; if bytes.len() % ule_bytes != 0 { return Err(ZeroVecError::length::<Self>(bytes.len()));
} for chunk in bytes.chunks(ule_bytes) { letmut i = 0;
$( let j = i;
i += mem::size_of::<$t>(); #[allow(clippy::indexing_slicing)] // length checked
<$t>::validate_byte_slice(&chunk[j..i])?;
)+
}
Ok(())
}
}
impl<$($t: AsULE),+> AsULE for ($($t),+) { type ULE = $name<$(<$t>::ULE),+>;
// We need manual impls since `#[derive()]` is disallowed on packed types impl<$($t: PartialEq + ULE),+> PartialEq for $name<$($t),+> { fn eq(&self, other: &Self) -> bool {
($(self.$i),+).eq(&($(other.$i),+))
}
}
impl<'a, $($t: Ord + AsULE + 'static),+> crate::map::ZeroMapKV<'a> for ($($t),+) { type Container = crate::ZeroVec<'a, ($($t),+)>; type Slice = crate::ZeroSlice<($($t),+)>; type GetType = $name<$(<$t>::ULE),+>; type OwnedType = ($($t),+);
}
};
}
tuple_ule!(Tuple2ULE, "2", [ A 0, B 1 ]);
tuple_ule!(Tuple3ULE, "3", [ A 0, B 1, C 2 ]);
tuple_ule!(Tuple4ULE, "4", [ A 0, B 1, C 2, D 3 ]);
tuple_ule!(Tuple5ULE, "5", [ A 0, B 1, C 2, D 3, E 4 ]);
tuple_ule!(Tuple6ULE, "6", [ A 0, B 1, C 2, D 3, E 4, F 5 ]);
#[test] fn test_pairule_validate() { usecrate::ZeroVec; let vec: Vec<(u32, char)> = vec![(1, 'a'), (1234901, '啊'), (100, 'अ')]; let zerovec: ZeroVec<(u32, char)> = vec.iter().copied().collect(); let bytes = zerovec.as_bytes(); let zerovec2 = ZeroVec::parse_byte_slice(bytes).unwrap();
assert_eq!(zerovec, zerovec2);
// Test failed validation with a correctly sized but differently constrained tuple // Note: 1234901 is not a valid char let zerovec3 = ZeroVec::<(char, u32)>::parse_byte_slice(bytes);
assert!(zerovec3.is_err());
}
#[test] fn test_tripleule_validate() { usecrate::ZeroVec; let vec: Vec<(u32, char, i8)> = vec![(1, 'a', -5), (1234901, '啊', 3), (100, 'अ', -127)]; let zerovec: ZeroVec<(u32, char, i8)> = vec.iter().copied().collect(); let bytes = zerovec.as_bytes(); let zerovec2 = ZeroVec::parse_byte_slice(bytes).unwrap();
assert_eq!(zerovec, zerovec2);
// Test failed validation with a correctly sized but differently constrained tuple // Note: 1234901 is not a valid char let zerovec3 = ZeroVec::<(char, i8, u32)>::parse_byte_slice(bytes);
assert!(zerovec3.is_err());
}
// Test failed validation with a correctly sized but differently constrained tuple // Note: 1234901 is not a valid char let zerovec3 = ZeroVec::<(char, i8, u16, u32)>::parse_byte_slice(bytes);
assert!(zerovec3.is_err());
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.20 Sekunden
(vorverarbeitet am 2026-06-19)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.