Expand description
§Magnet, a JSON/BSON schema generator
These two related crates, magnet_schema and magnet_derive define
a trait, BsonSchema, and a proc-macro derive for the same trait,
which allows types to easily implement JSON schema validation for
use with MongoDB.
The trait defines a single function, bson_schema(), that returns
a BSON Document describing the validation schema of the type based
on its fields (for structs and tuples), variants (for enums), or
elements/entries (for array- and map-like types).
The types are expected to be serialized and deserialized using Serde,
and generally Magnet will try very hard to respect #[serde(...)]
annotations as faithfully as possible, but no Serialize + Deserialize
trait bounds are enforced on the types as this is not strictly necessary.
§Usage Example
#[macro_use]
extern crate serde_derive;
extern crate serde;
#[macro_use]
extern crate bson;
#[macro_use]
extern crate magnet_derive;
extern crate magnet_schema;
use std::collections::HashSet;
use magnet_schema::BsonSchema;
#[derive(BsonSchema)]
struct Person {
name: String,
nicknames: HashSet<String>,
age: usize,
contact: Option<Contact>,
}
#[derive(BsonSchema, Serialize, Deserialize)]
#[serde(tag = "type", content = "value")]
enum Contact {
Email(String),
Phone(u64),
}
fn main() {
println!("{:#?}", Person::bson_schema());
}§Custom Attributes
-
#[serde(rename = "new_name")]: Magnet will respect Serde’s field/variant renaming attribute by default. -
#[serde(rename_all = "rename_rule")]: it will also respect Serde’srename_allrule. -
#[magnet(min_incl = "-1337")]— enforces an inclusive minimum for fields of numeric types -
#[magnet(min_excl = "42")]— enforces an exclusive “minimum” (infimum) for fields of numeric types -
#[magnet(max_incl = "63")]— enforces an inclusive maximum for fields of numeric types -
#[magnet(max_excl = "64")]— enforces an exclusive “maximum” (supremum) for fields of numeric types
§Development Roadmap
-
[x]DefineBsonSchematrait -
[x]impl BsonSchemafor most primitives/std::types -
[x]Cargofeatures for implementingBsonSchemafor “atomic” types in foreign crates, for instance,url::Urlanduuid::Uuid. -
[x]#[derive(BsonSchema)]on regular, named-field structs -
[x]#[derive(BsonSchema)]on newtype structs -
[x]#[derive(BsonSchema)]on tuple structs -
[x]#[derive(BsonSchema)]on unit structs -
[ ]#[derive(BsonSchema)]on enums-
[x]unit variants -
[ ]newtype variants-
[x]newtype variants around structs and maps -
[ ]newtype variants around inner, transitiveenums
-
-
[x]tuple variants -
[x]struct variants -
[x]respect Serde tagging conventions: external/internal/adjacent
-
-
[x]Respect more#[serde(...)]attributes, for example:rename,rename_all -
[ ]Respect more#[serde(...)]attributes, for example:default,skip,skip_serializing,skip_deserializing -
[x]Handle generic types in proc-macro derive -
[ ]Standard (non-MongoDB-specific) JSON schema support (approach?) -
[x]unit tests -
[x]documentation for attributes -
[ ]impl BsonSchemafor more esoteric primitives/standard types such as specialization of[u8]/Vec<u8>as binary, adding a validation regex"pattern"toPathandPathBuf, etc. -
[ ]Add our own attributes-
[x]magnet(rename = "...")— renames the field or variant to the name specified as the value of therenameattribute -
[ ]magnet(regex = "foo?|[ba]r{3,6}")— custom validation; implies"type": "string". Patterns are implicitly enclosed between^...$for robustness. -
[ ]magnet(unsafe_regex = "^nasty-regex$")— just likemagnet(regex), but no automatic enclosing in^...$happens. This may allow invalid data to pass validation!!! -
[ ]magnet(non_empty)— for collections: same asmin_length = "1". -
[ ]magnet(min_length = "16")— for collections/tuples etc. -
[ ]magnet(max_length = "32")— for collections/tuples etc. -
[x]magnet(min_incl = "-1337")— inclusive minimum for numbers -
[x]magnet(min_excl = "42")— exclusive “minimum” (infimum) for numbers -
[x]magnet(max_incl = "63")— inclusive maximum for numbers -
[x]magnet(max_excl = "64")— exclusive “maximum” (supremum) for numbers -
[ ]magnet(allow_extra_fields)— sets"additionalProperties": true. By default, Magnet sets this field tofalsefor maximal safety. Allowing arbitrary data to be inserted in a DB is generally a Bad Idea, as it may lead to code injection (MongoDBsupports storing JavaScript in a collection! Madness!) or at best, denial-of-service (DoS) attacks. -
[ ]magnet(allow_extra_fields = "ExtraFieldType")— sets"additionalProperties": ExtraFieldType::bson_schema(), so that unlisted additional object fields are allowed provided that they conform to the schema of the specified type.
-
Traits§
- Bson
Schema - Types which can be expressed/validated by a MongoDB-flavored JSON schema.