postcard_schema/
lib.rs

1#![cfg_attr(not(any(test, feature = "use-std")), no_std)]
2#![warn(missing_docs)]
3#![cfg_attr(docsrs, feature(doc_cfg))]
4//! # Postcard Schema
5
6pub mod impls;
7pub mod key;
8pub mod schema;
9
10/// Derive [`Schema`] for a struct or enum
11///
12/// # Examples
13///
14/// ```
15/// use postcard_schema::Schema;
16///
17/// #[derive(Schema)]
18/// struct Point {
19///     x: i32,
20///     y: i32,
21/// }
22/// ```
23///
24/// # Attributes
25///
26/// ## `#[postcard(crate = ...)]`
27///
28/// The `#[postcard(crate = ...)]` attribute can be used to specify a path to the `postcard_schema`
29/// crate instance to use when referring to [`Schema`] and [schema types](schema) from generated
30/// code. This is normally only applicable when invoking re-exported derives from a different crate.
31///
32/// ```
33/// # use postcard_schema::Schema;
34/// use postcard_schema as reexported_postcard_schema;
35///
36/// #[derive(Schema)]
37/// #[postcard(crate = reexported_postcard_schema)]
38/// struct Point {
39///     x: i32,
40///     y: i32,
41/// }
42/// ```
43///
44/// ## `#[postcard(bound = ...)]`
45///
46/// The `#[postcard(bound = ...)]` attribute can be used to overwrite the default bounds when
47/// deriving [`Schema`]. The default bounds are `T: Schema` for each type parameter `T`.
48///
49/// ```
50/// # use postcard_schema::Schema;
51/// #[derive(Schema)]
52/// #[postcard(bound = "")]
53/// struct Foo<F: Bar, T: Schema>(F::Wrap<T>);
54///
55/// trait Bar {
56///     type Wrap<T: Schema>: Schema;
57/// }
58///
59/// struct NoSchema;
60/// impl Bar for NoSchema {
61///     type Wrap<T: Schema> = Option<T>;
62/// }
63///
64/// Foo::<NoSchema, u8>::SCHEMA;
65/// ```
66#[cfg(feature = "derive")]
67pub use postcard_derive::Schema;
68
69/// A trait that represents a compile time calculated schema
70pub trait Schema {
71    /// A recursive data structure that describes the schema of the given
72    /// type.
73    const SCHEMA: &'static schema::NamedType;
74}
75
76#[cfg(test)]
77mod tests {
78    use super::*;
79
80    #[test]
81    fn crate_path() {
82        #[allow(unused)]
83        #[derive(Schema)]
84        #[postcard(crate = crate)]
85        struct Point {
86            x: i32,
87            y: i32,
88        }
89
90        assert_eq!(
91            Point::SCHEMA,
92            &schema::NamedType {
93                name: "Point",
94                ty: &schema::DataModelType::Struct(&[
95                    &schema::NamedValue {
96                        name: "x",
97                        ty: i32::SCHEMA
98                    },
99                    &schema::NamedValue {
100                        name: "y",
101                        ty: i32::SCHEMA
102                    },
103                ])
104            }
105        );
106    }
107}