Crate magnet_schema[−][src]
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 struct
s and tuples), variants (for enum
s), 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_all
rule. -
#[magnet(top_level_id)]
- when this attribute is present on a type, an"_id"
field with the value<bson::oid::ObjectId as BsonSchema>::bson_schema()
will be added to the generated schema of the type. This is intended to be used with top-level documents which are added directly to a MongoDB collection but which make no use of the always-present_id
field. -
#[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]
DefineBsonSchema
trait -
[x]
impl BsonSchema
for most primitives/std::
types -
[x]
Cargofeature
s for implementingBsonSchema
for "atomic" types in foreign crates, for instance,url::Url
anduuid::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, transitiveenum
s
-
-
[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 BsonSchema
for more esoteric primitives/standard types such as specialization of[u8]
/Vec<u8>
as binary, adding a validation regex"pattern"
toPath
andPathBuf
, etc. -
[ ]
Add our own attributes-
[x]
magnet(rename = "...")
— renames the field or variant to the name specified as the value of therename
attribute -
[ ]
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 tofalse
for maximal safety. Allowing arbitrary data to be inserted in a DB is generally a Bad Idea, as it may lead to code injection (MongoDB
supports 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
BsonSchema |
Types which can be expressed/validated by a MongoDB-flavored JSON schema. |