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