1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
//! //! *Alkahest* is serialization library aimed for packet writing and reading in hot path. //! For this purpose *Alkahest* avoids allocations and reads data only on demand. //! //! Key differences of *Alkahest* from other popular serialization crates is zero-overhead serialization and zero-copy lazy deserialization.\ //! For example to serialize value sequence it is not necessary to construct expensive type with allocations such as vectors.\ //! Instead sequences are serialized directly from iterators. On deserialization an iterator is returned to the user, which does not parse any element before it is requested. //! Which means that data that is not accessed - not parsed either. //! //! *Alkahest* works similarly to *FlatBuffers*,\ //! but does not require using another language for data scheme definition and running external tool,\ //! and supports generic schemas. //! #![no_std] #![forbid(unsafe_code)] mod bytes; mod primitive; mod schema; mod seq; use core::mem::size_of; pub use self::{ bytes::Bytes, schema::{Pack, Packed, Schema, SchemaUnpack, Unpacked}, seq::{Seq, SeqUnpacked}, }; #[cfg(feature = "derive")] pub use alkahest_proc::Schema; // Exports for proc-macro. #[doc(hidden)] pub use bytemuck::{Pod, Zeroable}; /// Writes data into bytes slice. /// Returns number of bytes written. /// /// # Panics /// /// Panics if value doesn't fit into bytes. pub fn write<'a, T, P>(bytes: &'a mut [u8], packable: P) -> usize where T: Schema, P: Pack<T>, { let packed_size = size_of::<T::Packed>(); let (packed, used) = packable.pack(packed_size, &mut bytes[packed_size..]); bytes[..packed_size].copy_from_slice(bytemuck::bytes_of(&packed)); packed_size + used } /// Reads and unpacks package from raw bytes. /// /// # Panics /// /// This function or returned value's methods may panic /// if `bytes` slice does not contain data written with same schema. pub fn read<'a, T>(bytes: &'a [u8]) -> Unpacked<'a, T> where T: Schema, { T::unpack( *bytemuck::from_bytes(&bytes[..size_of::<T::Packed>()]), bytes, ) } /// Type used to represent sizes and offsets in alkahest packages. /// This places limitation on sequence sizes which practically is never hit. /// `usize` itself is not portable and cannot be written into alkahest package. #[doc(hidden)] pub type FixedUsize = u32;