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