1mod timestamp;
13
14pub use timestamp::Time;
17
18use std::borrow::Cow;
22use std::marker::PhantomData;
23use std::num::NonZeroU32;
24use std::sync::Arc;
25
26use crate::__private::{PostcardReader, PostcardValue};
30use crate::schema::declaration::{self, Field, Kind};
31use crate::schema::{Cardinality, Described};
32use crate::{Identifier, MemorySize, MessageError};
33
34macro_rules! product {
39 ($ty:ty { $($field:ident: $codec:ty => $tag:literal),* $(,)? }) => {
40 crate::model::storage::codec::product!($ty { $($field: $codec => $tag),* }, check = |_: &$ty| Ok(()));
41 };
42 ($ty:ty { $($field:ident: $codec:ty => $tag:literal),* $(,)? }, check = $check:expr) => {
43 impl crate::schema::Described for $ty {
44 const NAME: &'static str = concat!(module_path!(), "::", stringify!($ty));
45 const FIELDS: &'static [crate::schema::declaration::Field] = &[$(crate::schema::declaration::Field {
46 name: std::borrow::Cow::Borrowed(stringify!($field)),
47 tag: $tag,
48 kind: <$codec as crate::model::storage::codec::Value>::KIND,
49 cardinality: <$codec as crate::model::storage::codec::Value>::CARDINALITY,
50 }),*];
51
52 const MARKER: &'static [u8] = &crate::schema::declaration::encode::<{
53 crate::schema::declaration::encoded_len(Self::NAME, Self::FIELDS)
54 }>(Self::NAME, Self::FIELDS);
55}
56 #[allow(unused_variables)]
57 impl crate::__private::PostcardValue for $ty {
58 fn write(&self, bytes: &mut Vec<u8>) {
59 $(<$codec as crate::model::storage::codec::Value>::postcard_write(&self.$field, bytes);)*
60 }
61 fn size(&self) -> usize {
62 0usize$(.saturating_add(<$codec as crate::model::storage::codec::Value>::postcard_size(&self.$field)))*
63 }
64 fn memory(input: &mut crate::__private::PostcardReader<'_>) -> std::result::Result<usize, crate::MessageError> {
65 input.nested(|input| {
66 let memory = std::mem::size_of::<Self>();
67 $(let memory = crate::__private::decoding_add(memory, <$codec as crate::model::storage::codec::Value>::postcard_memory(input)?)?;)*
68 Ok(memory)
69 })
70 }
71 fn read(input: &mut crate::__private::PostcardReader<'_>) -> std::result::Result<Self, crate::MessageError> {
72 let value = input.nested(|input| Ok(Self { $($field: <$codec as crate::model::storage::codec::Value>::postcard_read(input)?),* }))?;
73 let check: fn(&Self) -> std::result::Result<(), crate::MessageError> = $check;
74 check(&value)?;
75 Ok(value)
76 }
77 }
78 };
79}
80
81pub(crate) use product;
82
83macro_rules! postcard_field {
84 () => {
85 fn postcard_write(value: &Self::Native, bytes: &mut Vec<u8>) {
86 crate::__private::PostcardValue::write(value, bytes);
87 }
88 fn postcard_size(value: &Self::Native) -> usize {
89 crate::__private::PostcardValue::size(value)
90 }
91 fn postcard_memory(input: &mut crate::__private::PostcardReader<'_>) -> std::result::Result<usize, crate::MessageError> {
92 Ok(<Self::Native as crate::__private::PostcardValue>::memory(input)?.saturating_sub(std::mem::size_of::<Self::Native>()))
93 }
94 fn postcard_read(input: &mut crate::__private::PostcardReader<'_>) -> std::result::Result<Self::Native, crate::MessageError> {
95 <Self::Native as crate::__private::PostcardValue>::read(input)
96 }
97 };
98}
99pub(crate) use postcard_field;
100
101macro_rules! variants {
102 ($ty:ty { $($index:literal, $tag:literal, $name:literal: $pat:pat => { $($field:ident: $codec:ty => $ftag:literal),* $(,)? } => $build:expr;)+ }) => {
103 const _: () = {
104 struct Variant<const TAG: u32>;
105 $(impl crate::schema::Described for Variant<$tag> {
106 const NAME: &'static str = concat!(module_path!(), "::", stringify!($ty), "::", $name);
107 const FIELDS: &'static [crate::schema::declaration::Field] = &[$(crate::schema::declaration::Field {
108 name: std::borrow::Cow::Borrowed(stringify!($field)), tag: $ftag,
109 kind: <$codec as crate::model::storage::codec::Value>::KIND,
110 cardinality: <$codec as crate::model::storage::codec::Value>::CARDINALITY,
111 }),*];
112 const MARKER: &'static [u8] = &crate::schema::declaration::encode::<{
113 crate::schema::declaration::encoded_len(Self::NAME, Self::FIELDS)
114 }>(Self::NAME, Self::FIELDS);
115 })+
116 impl crate::schema::Described for $ty {
117 const NAME: &'static str = concat!(module_path!(), "::", stringify!($ty));
118 const FIELDS: &'static [crate::schema::declaration::Field] = &[$(crate::schema::declaration::Field {
119 name: std::borrow::Cow::Borrowed($name),
120 tag: $tag,
121 cardinality: crate::schema::Cardinality::Variant,
122 kind: crate::schema::declaration::Kind::Message {
123 definition: <Variant<$tag> as crate::schema::Described>::DEFINITION,
124 },
125 }),+];
126
127 const DEFAULT_VARIANT: Option<usize> = None;
129 const MARKER: &'static [u8] = &crate::schema::declaration::encode::<{
130 crate::schema::declaration::encoded_len(Self::NAME, Self::FIELDS)
131 }>(Self::NAME, Self::FIELDS);
132}
133 impl crate::__private::PostcardValue for $ty {
134 #[allow(unused_variables)]
135 fn write(&self, bytes: &mut Vec<u8>) {
136 match self {
137 $($pat => {
138 crate::__private::PostcardValue::write(&($index as u32), bytes);
139 $(<$codec as crate::model::storage::codec::Value>::postcard_write($field, bytes);)*
140 })+
141 }
142 }
143 #[allow(unused_variables)]
144 fn size(&self) -> usize {
145 match self {
146 $($pat => crate::__private::PostcardValue::size(&($index as u32))
147 $(.saturating_add(<$codec as crate::model::storage::codec::Value>::postcard_size($field)))*,)+
148 }
149 }
150 fn memory(input: &mut crate::__private::PostcardReader<'_>) -> std::result::Result<usize, crate::MessageError> {
151 input.nested(|input| {
152 let memory = std::mem::size_of::<Self>();
153 match input.value::<u32>()? {
154 $($index => {
155 $(let memory = crate::__private::decoding_add(memory, <$codec as crate::model::storage::codec::Value>::postcard_memory(input)?)?;)*
156 Ok(memory)
157 })+
158 _ => Err(crate::MessageError::borrowed(concat!("unknown ", stringify!($ty), " variant"))),
159 }
160 })
161 }
162 fn read(input: &mut crate::__private::PostcardReader<'_>) -> std::result::Result<Self, crate::MessageError> {
163 input.nested(|input| match input.value::<u32>()? {
164 $($index => {
165 $(let $field = <$codec as crate::model::storage::codec::Value>::postcard_read(input)?;)*
166 Ok($build)
167 })+
168 _ => Err(crate::MessageError::borrowed(concat!("unknown ", stringify!($ty), " variant"))),
169 })
170 }
171 }
172 };
173 };
174}
175pub(crate) use variants;
176
177macro_rules! coded {
178 ($ty:ident { $($variant:ident),+ $(,)? }) => {
179 impl crate::model::storage::codec::Coded for $ty {
180 const NAME: &'static str = concat!(module_path!(), "::", stringify!($ty));
181 const VARIANTS: &'static [Self] = &[$(Self::$variant),+];
182 }
183 };
184}
185pub(crate) use coded;
186
187type Result<T, E = MessageError> = std::result::Result<T, E>;
190
191pub struct Repeated<T>(PhantomData<fn() -> T>);
194pub struct Nested<T>(PhantomData<fn() -> T>);
195pub struct Shared<T>(PhantomData<fn() -> T>);
196pub struct Optional<T>(PhantomData<fn() -> T>);
197pub struct Id;
198pub struct Bytes;
199pub struct Unsigned;
200pub struct Percent;
201pub struct Version;
202pub struct Flag;
203pub struct Signed;
204pub struct Float;
205pub struct Text;
206pub struct Code<E>(PhantomData<fn() -> E>);
207pub struct Index;
208pub struct Wide;
209pub struct WideNonZero;
210pub struct WideSigned;
211pub struct Wrap<A>(PhantomData<fn() -> A>);
212pub struct Many<A>(PhantomData<fn() -> A>);
213
214pub trait Native: PostcardValue + MemorySize + Described {}
219impl<T: PostcardValue + MemorySize + Described> Native for T {}
220
221pub trait Coded: Copy + PartialEq + Send + Sync + 'static {
222 const NAME: &'static str;
223 const VARIANTS: &'static [Self];
224 fn code(&self) -> u32 {
225 Self::VARIANTS
226 .iter()
227 .position(|variant| variant == self)
228 .and_then(|index| u32::try_from(index).ok())
229 .expect("a coded variant is listed")
230 }
231
232 fn from_code(code: u64) -> Result<Self> {
233 usize::try_from(code)
234 .ok()
235 .and_then(|index| Self::VARIANTS.get(index).copied())
236 .ok_or_else(|| MessageError::borrowed("unknown storage enum code"))
237 }
238}
239
240pub trait Value: 'static {
241 const NAME: &'static str;
242 type Native;
243 const KIND: Kind;
244 const CARDINALITY: Cardinality = Cardinality::Required;
245 fn postcard_write(value: &Self::Native, bytes: &mut Vec<u8>);
246 fn postcard_size(value: &Self::Native) -> usize;
247 fn postcard_memory(input: &mut PostcardReader<'_>) -> Result<usize>;
248 fn postcard_read(input: &mut PostcardReader<'_>) -> Result<Self::Native>;
249}
250
251impl<T: Native> Value for Repeated<T> {
254 const NAME: &'static str = declaration::Name::new(concat!(module_path!(), "::", stringify!(Repeated)), &[T::NAME]).as_str();
255 postcard_field!();
256 type Native = Vec<T>;
257 const KIND: Kind = Nested::<T>::KIND;
258 const CARDINALITY: Cardinality = Cardinality::Repeated;
259}
260
261impl<T: Native> Value for Nested<T> {
262 const NAME: &'static str = declaration::Name::new(concat!(module_path!(), "::", stringify!(Nested)), &[T::NAME]).as_str();
263 postcard_field!();
264 type Native = T;
265 const KIND: Kind = Kind::Message { definition: T::DEFINITION };
266}
267
268impl<T: Native> Value for Shared<T> {
269 const NAME: &'static str = Nested::<T>::NAME;
270 type Native = Arc<T>;
271 const KIND: Kind = Nested::<T>::KIND;
272
273 fn postcard_write(value: &Self::Native, bytes: &mut Vec<u8>) {
274 T::write(value, bytes);
275 }
276
277 fn postcard_size(value: &Self::Native) -> usize {
278 T::size(value)
279 }
280
281 fn postcard_memory(input: &mut PostcardReader<'_>) -> Result<usize> {
282 crate::__private::decoding_add(T::memory(input)?, 2 * std::mem::size_of::<usize>())
283 }
284
285 fn postcard_read(input: &mut PostcardReader<'_>) -> Result<Self::Native> {
286 T::read(input).map(Arc::new)
287 }
288}
289
290impl<T: Value> Value for Optional<T> {
291 const NAME: &'static str = declaration::Name::new(concat!(module_path!(), "::", stringify!(Optional)), &[T::NAME]).as_str();
292 fn postcard_write(value: &Self::Native, bytes: &mut Vec<u8>) {
293 PostcardValue::write(&value.is_some(), bytes);
294 if let Some(value) = value {
295 T::postcard_write(value, bytes);
296 }
297 }
298
299 fn postcard_size(value: &Self::Native) -> usize {
300 1usize.saturating_add(value.as_ref().map_or(0, T::postcard_size))
301 }
302
303 fn postcard_memory(input: &mut PostcardReader<'_>) -> Result<usize> {
304 input.nested(|input| if input.value::<bool>()? { T::postcard_memory(input) } else { Ok(0) })
305 }
306
307 fn postcard_read(input: &mut PostcardReader<'_>) -> Result<Self::Native> {
308 input.nested(|input| if input.value::<bool>()? { T::postcard_read(input).map(Some) } else { Ok(None) })
309 }
310
311 type Native = Option<T::Native>;
312 const KIND: Kind = T::KIND;
313 const CARDINALITY: Cardinality = Cardinality::Optional;
314}
315
316impl Value for Id {
317 const NAME: &'static str = concat!(module_path!(), "::", stringify!(Id));
318 postcard_field!();
319 type Native = Identifier;
320 const KIND: Kind = Kind::String;
321}
322
323impl Value for Bytes {
324 const NAME: &'static str = concat!(module_path!(), "::", stringify!(Bytes));
325 postcard_field!();
326 type Native = Vec<u8>;
327 const KIND: Kind = Kind::Bytes;
328}
329
330impl Value for Unsigned {
331 const NAME: &'static str = concat!(module_path!(), "::", stringify!(Unsigned));
332 postcard_field!();
333 type Native = u64;
334 const KIND: Kind = Kind::U64;
335}
336
337impl Value for Percent {
340 const NAME: &'static str = concat!(module_path!(), "::", stringify!(Percent));
341 postcard_field!();
342 type Native = u8;
343 const KIND: Kind = Kind::U32;
344}
345
346impl Value for Version {
347 const NAME: &'static str = concat!(module_path!(), "::", stringify!(Version));
348 postcard_field!();
349 type Native = NonZeroU32;
350 const KIND: Kind = Kind::U32;
351}
352
353macro_rules! varint {
354 ($adapter:ty, $native:ty, $kind:ident, $encoding:ident, $from:expr) => {
355 impl Value for $adapter {
356 const NAME: &'static str = concat!(module_path!(), "::", stringify!($adapter));
357 postcard_field!();
358 type Native = $native;
359 const KIND: Kind = Kind::$kind;
360 }
361 };
362}
363
364varint!(Flag, bool, Bool, bool, |value: u64| match value {
365 0 => Ok(false),
366 1 => Ok(true),
367 _ => Err(MessageError::borrowed("invalid storage boolean")),
368});
369varint!(Signed, i64, I64, int64, |value: u64| Ok(value as i64));
370
371impl Value for Float {
372 const NAME: &'static str = concat!(module_path!(), "::", stringify!(Float));
373 postcard_field!();
374 type Native = f64;
375 const KIND: Kind = Kind::F64;
376}
377
378impl Value for Text {
379 const NAME: &'static str = concat!(module_path!(), "::", stringify!(Text));
380 postcard_field!();
381 type Native = String;
382 const KIND: Kind = Kind::String;
383}
384
385impl<E: Coded> Value for Code<E> {
386 const NAME: &'static str = declaration::Name::new(concat!(module_path!(), "::", stringify!(Code)), &[E::NAME]).as_str();
387 type Native = E;
388 const KIND: Kind = Kind::U32;
389 fn postcard_write(value: &E, bytes: &mut Vec<u8>) {
390 PostcardValue::write(&value.code(), bytes);
391 }
392
393 fn postcard_size(value: &E) -> usize {
394 PostcardValue::size(&value.code())
395 }
396
397 fn postcard_memory(input: &mut PostcardReader<'_>) -> Result<usize> {
398 E::from_code(u64::from(input.value::<u32>()?))?;
399 Ok(0)
400 }
401
402 fn postcard_read(input: &mut PostcardReader<'_>) -> Result<E> {
403 E::from_code(u64::from(input.value::<u32>()?))
404 }
405}
406
407fn host_width(value: u64) -> Result<usize> {
409 usize::try_from(value).map_err(|_| MessageError::borrowed("index exceeds host width"))
410}
411
412impl Value for Index {
413 const NAME: &'static str = concat!(module_path!(), "::", stringify!(Index));
414 type Native = usize;
415 const KIND: Kind = Kind::U64;
416 fn postcard_write(value: &usize, bytes: &mut Vec<u8>) {
417 PostcardValue::write(&(*value as u64), bytes);
418 }
419
420 fn postcard_size(value: &usize) -> usize {
421 PostcardValue::size(&(*value as u64))
422 }
423
424 fn postcard_memory(input: &mut PostcardReader<'_>) -> Result<usize> {
425 Self::postcard_read(input)?;
426 Ok(0)
427 }
428
429 fn postcard_read(input: &mut PostcardReader<'_>) -> Result<usize> {
430 host_width(input.value::<u64>()?)
431 }
432}
433
434macro_rules! wide {
436 ($adapter:ty, $native:ty, $high:ty, $high_codec:ty, $split:expr, $join:expr) => {
437 impl Described for $adapter {
438 const NAME: &'static str = <Self as Value>::NAME;
439 const FIELDS: &'static [Field] = &[
440 crate::schema::declaration::Field {
441 name: Cow::Borrowed("high"),
442 tag: 1,
443 kind: <$high_codec as Value>::KIND,
444 cardinality: Cardinality::Required,
445 },
446 crate::schema::declaration::Field {
447 name: Cow::Borrowed("low"),
448 tag: 2,
449 kind: Kind::U64,
450 cardinality: Cardinality::Required,
451 },
452 ];
453 const MARKER: &'static [u8] = &declaration::encode::<{ declaration::encoded_len(<Self as Described>::NAME, Self::FIELDS) }>(
454 <Self as Described>::NAME,
455 Self::FIELDS,
456 );
457 }
458 impl Value for $adapter {
459 const NAME: &'static str = concat!(module_path!(), "::", stringify!($adapter));
460 type Native = $native;
461 const KIND: Kind = Kind::Message { definition: <Self as Described>::DEFINITION };
462 fn postcard_write(value: &$native, bytes: &mut Vec<u8>) {
463 let (high, low): ($high, u64) = ($split)(*value);
464 PostcardValue::write(&high, bytes);
465 PostcardValue::write(&low, bytes);
466 }
467 fn postcard_size(value: &$native) -> usize {
468 let (high, low): ($high, u64) = ($split)(*value);
469 PostcardValue::size(&high).saturating_add(PostcardValue::size(&low))
470 }
471 fn postcard_memory(input: &mut PostcardReader<'_>) -> Result<usize> {
472 Self::postcard_read(input)?;
473 Ok(0)
474 }
475 fn postcard_read(input: &mut PostcardReader<'_>) -> Result<$native> {
476 let high = input.value::<$high>()?;
477 let low = input.value::<u64>()?;
478 ($join)(high, low)
479 }
480 }
481 };
482}
483
484wide!(Wide, u128, u64, Unsigned, |value: u128| ((value >> 64) as u64, value as u64), |high: u64, low: u64| Ok::<_, MessageError>(
485 (u128::from(high) << 64) | u128::from(low)
486));
487wide!(
488 WideNonZero,
489 std::num::NonZeroU128,
490 u64,
491 Unsigned,
492 |value: std::num::NonZeroU128| ((value.get() >> 64) as u64, value.get() as u64),
493 |high: u64, low: u64| std::num::NonZeroU128::new((u128::from(high) << 64) | u128::from(low))
494 .ok_or_else(|| MessageError::borrowed("wide value must be nonzero"))
495);
496wide!(WideSigned, i128, i64, Signed, |value: i128| ((value >> 64) as i64, value as u64), |high: i64, low: u64| Ok::<_, MessageError>(
497 (i128::from(high) << 64) | i128::from(low)
498));
499
500impl<A: Value> Described for Wrap<A> {
502 const NAME: &'static str = <Self as Value>::NAME;
503 const FIELDS: &'static [Field] =
504 &[crate::schema::declaration::Field { name: Cow::Borrowed("value"), tag: 1, kind: A::KIND, cardinality: A::CARDINALITY }];
505 const MARKER: &'static [u8] = declaration::encode_buffer::<2048>(<Self as Described>::NAME, Self::FIELDS)
506 .split_at(declaration::encoded_len(<Self as Described>::NAME, Self::FIELDS))
507 .0;
508}
509impl<A: Value> Value for Wrap<A> {
510 const NAME: &'static str = declaration::Name::new(concat!(module_path!(), "::", stringify!(Wrap)), &[A::NAME]).as_str();
511 type Native = A::Native;
512 const KIND: Kind = Kind::Message { definition: <Self as Described>::DEFINITION };
513 fn postcard_write(value: &A::Native, bytes: &mut Vec<u8>) {
514 A::postcard_write(value, bytes);
515 }
516
517 fn postcard_size(value: &A::Native) -> usize {
518 A::postcard_size(value)
519 }
520
521 fn postcard_memory(input: &mut PostcardReader<'_>) -> Result<usize> {
522 A::postcard_memory(input)
523 }
524
525 fn postcard_read(input: &mut PostcardReader<'_>) -> Result<A::Native> {
526 A::postcard_read(input)
527 }
528}
529
530impl<A: Value> Value for Many<A> {
532 const NAME: &'static str = declaration::Name::new(concat!(module_path!(), "::", stringify!(Many)), &[A::NAME]).as_str();
533 type Native = Vec<A::Native>;
534 const KIND: Kind = Wrap::<A>::KIND;
535 const CARDINALITY: Cardinality = Cardinality::Repeated;
536 fn postcard_write(values: &Vec<A::Native>, bytes: &mut Vec<u8>) {
537 PostcardValue::write(&(values.len() as u64), bytes);
538 for value in values {
539 A::postcard_write(value, bytes);
540 }
541 }
542
543 fn postcard_size(values: &Vec<A::Native>) -> usize {
544 values.iter().fold(PostcardValue::size(&(values.len() as u64)), |size, value| size.saturating_add(A::postcard_size(value)))
545 }
546
547 fn postcard_memory(input: &mut PostcardReader<'_>) -> Result<usize> {
548 let count = host_width(input.value::<u64>()?)?;
549 input.claim(count)?;
550 let mut memory = crate::__private::decoding_multiply(count, std::mem::size_of::<A::Native>())?;
551 for _ in 0..count {
552 memory = crate::__private::decoding_add(memory, A::postcard_memory(input)?)?;
553 }
554 Ok(memory)
555 }
556
557 fn postcard_read(input: &mut PostcardReader<'_>) -> Result<Vec<A::Native>> {
558 let count = host_width(input.value::<u64>()?)?;
559 input.claim(count)?;
560 let mut values = crate::__private::decoding_vector(count)?;
561 for _ in 0..count {
562 values.push(A::postcard_read(input)?);
563 }
564 Ok(values)
565 }
566}
567
568