Json schema
Hi, You described crate as JSON/BSON schema generator. But for now there is no Json schema generator (or I can't find)? Do you have plan to add it?
For example: Generate from rust struct used bson_schema().
{
"type": "object",
"additionalProperties": false,
"required": [
"i"
],
"properties": {
"i": {
"bsonType": [
"int",
"long"
],
"minimum": -2147483648,
"maximum": 2147483647
}
}
}
for json should looks like this:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"i": {
"type": "integer",
"minimum": -2147483648,
"maximum": 2147483647
}
},
"required": [
"i"
]
}
I am not using it with mongo, so question is that u want to make it more general?
Hi, and thanks for contributing!
Yes, generation of regular standard-conformant JSON schemas is also planned, it's just that I needed this for MongoDB validation so that was the first thing I implemented. The code needs some refactoring anyway, because the way it handles some features (e.g. enum tagging and maximum/minimum bounds) got a bit convoluted, but after that, two additional things should be possible:
– JSON schema generation and
– adding comment fields based on doc comments for human consumers of the schemas (there's an outstanding partial pull request for it already).
Great. I need JSON schema to my project. I am new to rust macros. But if u have some plan how to refactor and describe how would u like API should be. I can try submit PR.
Are u plan to support just draft4 or draft7 also?
I think if we adhere to a standard it might as well be the latest one, so I'd say let's target v7 unless there's something in it that's excessively difficult to implement (I haven't yet looked at the differences, will do during the weekend.)
Feel free to notify me with your plan of impl/refactor. I am rather junior but I will try help if you wish.
Hi guys,
Any update on your plan regarding this json schema generator? I may be able to contribute, also, I expect also some convergence with serde json. Perhaps you already have some good view on the next steps to get a good json schema generator
Hey there! Unfortunately, these days I have very little time to add new features. 😞 Implementing this without excessive code copy-and-paste would require at least some sort of refactoring. Anyone is welcome to start that, so if you're interested, let me explain it in more detail.
Yes, sure, please share your plan for refactoring/impl. I'll see how I can contribute.
Awesome! So, here are a couple of things – this list is possibly (likely) non-exhaustive, so I'll have to trust you with good taste and style:
-
The
magnet_schemacrate:-
Add the
serde_jsondependency toCargo.tomland theextern cratedeclaration tolib.rs -
Add the definition of the
JsonSchematrait, based onBsonSchema, like this:use serde_json::Value; /// Types which can be expressed/validated by a standard v7 JSON schema. pub trait JsonSchema { /// Returns a JSON value describing the JSON schema of this type. fn json_schema() -> Value; } -
Implement
JsonSchemafor the relevant primitive andstd::types, based on the JSON schema v7 spec and following the examples ofimpl BsonSchemafor the same types in the crate. -
support.rsneeds some more love too, you'll probably need to implement the already-existing functions forserde_json::Valuetoo. I don't know how similar they will be to the existing ones (arising out of necessity), but if they do turn out to be very similar, you should probably think about changing the functions over concrete types into generics, and indirectly using a trait instead, implemented by bothbson::Documentandserde_json::Value, for extending and modifying JSON/BSON schema contents.
-
-
The
magnet_derivecrate:- Add the derive proc-macro for the
JsonSchematrait It will probably look like:#[proc_macro_derive(JsonSchema, attributes(magnet))] pub fn derive_json_schema(input: TokenStream) -> TokenStream { … } - Add its actual implementation, like:
// Implements `JsonSchema` for a given type based on its /// recursively contained types in fields or variants. fn impl_json_schema(input: TokenStream) -> Result<TokenStream> { … } - Generalize AST generator functions. The modus operandi of generalization should probably be the following:
- Add an
enum SchemaKind { Bson, Json } - Add a new argument to the functions in question:
kind: SchemaKind - When generating code that refers to
bson::{ Bson, Document }orserde_json::Valueor (perhaps even more importantly) the actual content of the resulting schema document (e.g. map keys, type names, etc…) switch on this schema kind argument to decide which one to generate. - Thinking about it, the approach in the previous bulletpoint can become messy. I could imagine this being implemented by various methods on
SchemaKindinstead, so the differences (and the data) are grouped together in a central location, and not dispersed around the entire code base, making it more data-oriented and less ad-hoc. - These AST generator functions reside in the following modules:
generics.rs(with_bson_schema()and the like should probably be renamedwith_schema(kind: SchemaKind))error.rs(just need to addJsonSchemain two doc comments)codegen_enum.rs,codegen_field.rs,codegen_struct.rs, andcodegen_union.rs
- Add an
- Add the derive proc-macro for the
Thanks for picking this up, and good luck!