[−][src]Crate conjure_codegen
Code generation for Conjure definitions.
Examples
Code generation via a build script, assuming we have a service-api.conjure.json file in the crate root:
build.rs:
use std::env; use std::path::Path; fn main() { let input = "service-api.conjure.json"; let output = Path::new(&env::var_os("OUT_DIR").unwrap()).join("service_api"); println!("cargo:rerun-if-changed={}", input); conjure_codegen::Config::new() .run_rustfmt(false) .generate_files(input, output) .unwrap(); }
src/lib.rs:
mod service_api { include!(concat!(env!("OUT_DIR"), "/service_api/mod.rs")); }
Types
Builtin
Builtin types map directly to existing Rust types:
| Conjure | Rust |
|---|---|
string | String |
datetime | chrono::DateTime<Utc> |
integer | i32 |
double | f64 |
safelong | conjure_object::SafeLong |
binary | serde_bytes::ByteBuf |
any | serde_value::Value |
boolean | bool |
uuid | uuid::Uuid |
rid | conjure_object::ResourceIdentifier |
bearertoken | conjure_object::BearerToken |
optional<T> | Option<T> |
list<T> | Vec<T> |
set<T> | BTreeSet<T> |
map<K, V> | BTreeMap<K, V> |
Many of these are exposed by the conjure-types crate, which is a required dependency of crates containing the
generated code.
Objects
Conjure objects turn into Rust structs along with builders used to construct them:
let object = ManyFieldExample::builder() .string("foo") .integer(123) .double_value(3.14) .optional_item("bar".to_string()) .items(vec!["hello".to_string(), "world".to_string()]) .alias(StringAliasExample("foobar".to_string())) .build(); assert_eq!(object.string(), "foo"); assert_eq!(object.optional_item(), Some("bar"));
The generated structs implement Debug, Clone, PartialEq, PartialOrd, Serialize, and Deserialize. They
also implement Eq, Ord, and Hash if they do not contain a double value, and Copy if they consist entirely
of copyable primitive types.
Unions
Conjure unions turn into Rust enums. By default, unions are extensible through an additional Unknown variant.
This allows unions to be forward-compatible by allowing clients to deserialize variants they don't yet know about
and reserialize them properly:
match union_value { UnionTypeExample::StringExample(string) => { // ... } UnionTypeExample::Set(set) => { // ... } // ... UnionTypeExample::Unknown(unknown) => { println!("got unknown variant: {}", unknown.type_()); } }
The generated enums implement Debug, Clone, PartialEq, PartialOrd, Serialize, and Deserialize. They
also implement Eq, Ord, and Hash if they do not contain a double value. Union variants which are themselves
unions are boxed in the generated enum to avoid self-referential type definitions.
Enums
Conjure enums turn into Rust enums. By default, enums are extensible. This allows enums to be forward-compatible by allowing clients to deserialize variants they don't yet know about and reserialize them properly:
match enum_value { EnumExample::One => println!("found one"), EnumExample::Two => println!("found two"), EnumExample::Unknown(unknown) => println!("got unknown variant: {}", unknown), }
The generated enums implement Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Display,
Serialize, and Deserialize.
Aliases
Conjure aliases turn into Rust newtype structs that act like their inner value:
let alias_value = StringAliasExample("hello world".to_string()); assert!(alias_value.starts_with("hello"));
The generated structs implement Deref, DerefMut, Debug, Clone, PartialEq, PartialOrd, Serialize, and
Deserialize. They also implement Eq, Ord, and Hash if they do not contain a double value, Copy if they
wrap a copyable primitive type, Default if they wrap a type implementing Default, and Display if they wrap a
type implementing Display.
Modules
| example_types | Examples of generated Conjure code. |
Structs
| Config | Codegen configuration. |