typify/
lib.rs

1// Copyright 2024 Oxide Computer Company
2
3//! # Typify
4//!
5//! Typify lets you convert JSON Schema documents into Rust types. It can be
6//! used via a macro [`import_types!`] or a `build.rs` file.
7//!
8//! A typical use looks like this:
9//! ```
10//! # use typify_macro::import_types;
11//! import_types!("../example.json");
12//! ```
13//!
14//! This expands to type definitions corresponding to the types from the file
15//! `example.json`. The types are `pub` and have a number of useful associated
16//! `impl`s including [Debug], [Clone],
17//! [Serialize](https://docs.rs/serde/latest/serde/trait.Serialize.html), and
18//! [Deserialize](https://docs.rs/serde/latest/serde/trait.Deserialize.html).
19//!
20//! Alternatively, you may use the expanded form:
21//! ```
22//! # use typify_macro::import_types;
23//! import_types!(schema = "../example.json");
24//! ```
25//!
26//! If you want to add additional derives for the generated types, you can
27//! specify them with the `derives` property of the expanded form:
28//! ```
29//! # use typify_macro::import_types;
30//! import_types!(
31//!     schema = "../example.json",
32//!     derives = [schemars::JsonSchema],
33//! );
34//! ```
35//!
36//! Generated structs can optionally include a builder-style interface:
37//! ```
38//! # mod x {
39//! # use typify_macro::import_types;
40//! import_types!(
41//!     schema = "../example.json",
42//!     struct_builder = true,
43//! );
44//! # }
45//! ```
46//!
47//! With this set, consumers can construct a struct `Veggie` as follows:
48//! ```
49//! # mod x {
50//! # use typify_macro::import_types;
51//! # import_types!(
52//! #    schema = "../example.json",
53//! #    struct_builder = true,
54//! # );
55//! # fn _x() {
56//! let veggie: Veggie = Veggie::builder()
57//!     .veggie_name("radish")
58//!     .veggie_like(true)
59//!     .try_into()
60//!     .unwrap();
61//! # }
62//! # }
63//! ```
64//!
65//! # Altering Conversion
66//!
67//! ## Renames and additional derivations
68//!
69//! You can specify renames types or add additional derive macros for generated
70//! types using the `patch` syntax:
71//! ```
72//! # use typify_macro::import_types;
73//! import_types!(
74//!     schema = "../example.json",
75//!     patch = {
76//!         Veggie = {
77//!             rename = "Vegetable",
78//!             derives = [ schemars::JsonSchema ],
79//!         }
80//!     }
81//! );
82//! ```
83//!
84//! ## Replacement types
85//!
86//! You can replace a generated type with an existing type by specifying an
87//! association between the name of a type with the type to use in its place:
88//! ```
89//! # mod my_fancy_networking_crate {
90//! # #[derive(serde::Deserialize)]
91//! # pub struct Ipv6Cidr(String);
92//! # }
93//! # use typify_macro::import_types;
94//! import_types!(
95//!     schema = "../example.json",
96//!     replace = {
97//!         Ipv6Cidr = my_fancy_networking_crate::Ipv6Cidr,
98//!     }
99//! );
100//! ```
101//!
102//! ## Conversion overrides
103//!
104//! You can override a conversion for a particular JSON schema construct by
105//! specifying an association between the schema and the type.
106//! ```
107//! # mod my_fancy_uuid_crate {
108//! # #[derive(serde::Deserialize)]
109//! # pub struct MyUuid(String);
110//! # }
111//! # use typify_macro::import_types;
112//! import_types!(
113//!     schema = "../example.json",
114//!     convert = {
115//!         {
116//!             type = "string",
117//!             format = "uuid",
118//!         } = my_fancy_uuid_crate::MyUuid,
119//!     }
120//! );
121//! ```
122//!
123//! # Macro vs. `build.rs`
124//!
125//! While using the [`import_types!`] macro is quite a bit simpler, you can
126//! also construct output in a `build.rs` script. Doing so requires a little
127//! more work to process the JSON Schema document and write out the file to
128//! your intended location. The biggest benefit is that the generated type
129//! definitions are significantly easier to inspect. The macro-generated types
130//! can be viewed with `cargo expand` and they (like `build.rs`-derived types)
131//! have generated documentation, but if you find that you'd like to see the
132//! actual code generated you may prefer a `build.rs`.
133//!
134//! ## Builder interface
135//!
136//! Typify exports a [TypeSpace] interface that is intended for programmatic
137//! construction of types. This can be for something simple like a `build.rs`
138//! script or something more complex like a generator whose input includes JSON
139//! schema type definitions.
140//!
141//! # Mapping JSON Schema to Rust
142//!
143//! JSON Schema allows for extreme flexibility. As such, there are some schemas
144//! that Typify isn't able to interpret (please file an issue!). In general,
145//! though, Typify does a pretty job of mapping JSON Schema types to Rust. For
146//! more information, see the project's
147//! [README.md](https://github.com/oxidecomputer/typify).
148
149#![deny(missing_docs)]
150
151pub use typify_impl::CrateVers;
152pub use typify_impl::Error;
153pub use typify_impl::Type;
154pub use typify_impl::TypeDetails;
155pub use typify_impl::TypeEnum;
156pub use typify_impl::TypeEnumVariant;
157pub use typify_impl::TypeId;
158pub use typify_impl::TypeNewtype;
159pub use typify_impl::TypeSpace;
160pub use typify_impl::TypeSpaceImpl;
161pub use typify_impl::TypeSpacePatch;
162pub use typify_impl::TypeSpaceSettings;
163pub use typify_impl::TypeStruct;
164pub use typify_impl::TypeStructPropInfo;
165pub use typify_impl::UnknownPolicy;
166#[cfg(feature = "macro")]
167pub use typify_macro::import_types;