From 6e1effab94e018c85762810b5a93b760f3302dc0 Mon Sep 17 00:00:00 2001 From: Alexander Polakov Date: Wed, 25 Jul 2018 01:53:09 +0300 Subject: [PATCH] Doc comments first try --- magnet_derive/src/codegen_enum.rs | 5 +++++ magnet_derive/src/codegen_field.rs | 27 +++++++++++++++++++-------- magnet_derive/src/meta.rs | 15 +++++++++++++++ magnet_schema/src/support.rs | 8 ++++++++ 4 files changed, 47 insertions(+), 8 deletions(-) diff --git a/magnet_derive/src/codegen_enum.rs b/magnet_derive/src/codegen_enum.rs index f4e6a1e..d50659c 100644 --- a/magnet_derive/src/codegen_enum.rs +++ b/magnet_derive/src/codegen_enum.rs @@ -16,6 +16,10 @@ pub fn impl_bson_schema_enum(attrs: Vec, ast: DataEnum) -> Result Some(meta_value_as_str(&s)?.parse()?), None => None, }; + let doc = doc_meta(&attrs).and_then(|doc| meta_value_as_str(&doc).ok()); + let doc = quote! { + "description": #doc + }; let tagging = SerdeEnumTag::from_attrs(&attrs)?; let variants: Vec<_> = ast.variants @@ -25,6 +29,7 @@ pub fn impl_bson_schema_enum(attrs: Vec, ast: DataEnum) -> Result { - impl_bson_schema_indexed_fields(fields.unnamed, extra) + impl_bson_schema_indexed_fields(attrs, fields.unnamed, extra) }, Fields::Unit => { assert!(extra.is_none(), "internally-tagged unit should've been handled"); @@ -51,10 +51,17 @@ fn impl_bson_schema_named_fields( ) -> Result { let properties = &field_names(attrs, &fields)?; let defs: Vec<_> = fields.iter().map(field_def).collect::>()?; + let doc = doc_meta(&attrs).and_then(|doc| meta_value_as_str(&doc).ok()); + let doc = if doc.is_some() { + quote! { "description": #doc.trim_left(), } + } else { + quote! {} + }; let tokens = if let Some(TagExtra { tag, variant }) = extra { quote! { doc! { "type": "object", + #doc "additionalProperties": false, "required": [ #tag, #(#properties,)* ], "properties": { @@ -67,6 +74,7 @@ fn impl_bson_schema_named_fields( quote! { doc! { "type": "object", + #doc "additionalProperties": false, "required": [ #(#properties,)* ], "properties": { @@ -90,15 +98,17 @@ fn field_def(field: &Field) -> Result { let max_excl = magnet_meta_name_value(&field.attrs, "max_excl")?; let lower = bounds_from_meta(min_incl, min_excl)?; let upper = bounds_from_meta(max_incl, max_excl)?; + let doc = doc_meta(&field.attrs).and_then(|doc| meta_value_as_str(&doc).ok()).unwrap_or_else(String::new); Ok(quote! { - ::magnet_schema::support::extend_schema_with_bounds( - <#ty as ::magnet_schema::BsonSchema>::bson_schema(), - ::magnet_schema::support::Bounds { - lower: #lower, - upper: #upper, - }, - ) + ::magnet_schema::support::extend_schema_with_doc( + ::magnet_schema::support::extend_schema_with_bounds( + <#ty as ::magnet_schema::BsonSchema>::bson_schema(), + ::magnet_schema::support::Bounds { + lower: #lower, + upper: #upper, + }, + ), #doc) }) } @@ -163,6 +173,7 @@ fn field_names(attrs: &[Attribute], fields: &Punctuated) -> Result /// Implements `BsonSchema` for a tuple `struct` or variant, /// with unnamed (numbered/indexed) fields. fn impl_bson_schema_indexed_fields( + attrs: &[Attribute], mut fields: Punctuated, extra: Option, ) -> Result { diff --git a/magnet_derive/src/meta.rs b/magnet_derive/src/meta.rs index bea8e73..be2fc74 100644 --- a/magnet_derive/src/meta.rs +++ b/magnet_derive/src/meta.rs @@ -4,6 +4,21 @@ use std::f64; use syn::{ Attribute, Meta, NestedMeta, MetaNameValue, Lit }; use error::{ Error, Result }; +pub fn doc_meta(attrs: &[Attribute]) -> Option { + let mut value = attrs.iter().filter_map(|attr| { + if let Some(meta) = attr.interpret_meta() { + match meta { + Meta::NameValue(ref val) if val.ident == "doc" => { + return Some(val.clone()) + } + _ => {}, + }; + } + None + }); + value.next() +} + /// Returns the inner, `...` part of the first `#[name(...)]` attribute /// with the specified name (like `#[magnet(key ( = "value")?)]`). /// TODO(H2CO3): check for duplicate arguments and bail out with an error diff --git a/magnet_schema/src/support.rs b/magnet_schema/src/support.rs index 3016048..987cc0a 100644 --- a/magnet_schema/src/support.rs +++ b/magnet_schema/src/support.rs @@ -56,6 +56,14 @@ pub fn extend_schema_with_bounds(mut schema: Document, bounds: Bounds) -> Docume schema } +#[doc(hidden)] +pub fn extend_schema_with_doc(mut schema: Document, doc: &str) -> Document { + if !doc.is_empty() { + schema.insert("description", doc.trim_left()); + } + schema +} + /// This function should not be used directly; calls to it are only generated by /// `magnet_derive` when emitting code for internally-tagged newtype variants. ///