Skip to content

Conversation

@polachok
Copy link

@polachok polachok commented Jul 25, 2018

Started working on #1

}
schema
}

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think here emptiness should be tested after trimming the doc-string.

) -> Result<TokenStream> {
let properties = &field_names(attrs, &fields)?;
let defs: Vec<_> = fields.iter().map(field_def).collect::<Result<_>>()?;
let doc = doc_meta(&attrs).and_then(|doc| meta_value_as_str(&doc).ok());
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do not use Result::ok() here – attribute parsing errors are meant to be propagated upward.

let doc = if doc.is_some() {
quote! { "description": #doc.trim_left(), }
} else {
quote! {}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this would be better served by

doc.map(|doc| quote! { "description": #doc.trim_left(), }).unwrap_or_default()

Also, the trailing comma should be at the use site for better readability.

Copy link
Author

@polachok polachok Jul 25, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm, but if #doc is empty it would error out for extra comma.
i guess i can do "description": #doc, so description would be there just empty

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, that is quite right. I didn't notice that. Nevermind, then. :)

Copy link
Owner

@H2CO3 H2CO3 Jul 25, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, that should also be true for the other similar places, then. For example, when doc == None, then wouldn't this also be a syntax error: codegen_enum.rs:19-22? I think that case might also be better written as mapping the whole quoted token stream over the optional doc comment, then unwrap_or_default()ing it at the end for an empty token stream id the comment is missing.

quote! {
doc! {
"type": "object",
#doc
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I mean, add a comma here…)

quote! {
doc! {
"type": "object",
#doc
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(…and here.)

upper: #upper,
},
)
::magnet_schema::support::extend_schema_with_doc(
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of wrapping each kind of extension into its own function, and increasing nesting, let's create a single extension context object and an extend_schema() function. The extension context object could contain all the potential extensions as optionals, and extend_schema() could apply them in one go. This sounds to me like a more principled and easier-to-understand approach.

schema
}

#[doc(hidden)]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Therefore, this function will not be necessary, its body will be incorporated into extend_schema().)

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);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please propagate the error here as well, instead of using .ok().

Copy link
Owner

@H2CO3 H2CO3 Jul 25, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, .unwrap_or_else(String::new) can be simplified to .unwrap_or_default().

use syn::{ Attribute, Meta, NestedMeta, MetaNameValue, Lit };
use error::{ Error, Result };

pub fn doc_meta(attrs: &[Attribute]) -> Option<MetaNameValue> {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add doc comments to all items (especially public ones). Running cargo +nightly clippy can show you wherever they are missing.


pub fn doc_meta(attrs: &[Attribute]) -> Option<MetaNameValue> {
let mut value = attrs.iter().filter_map(|attr| {
if let Some(meta) = attr.interpret_meta() {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be simplified to:

attr.interpret_meta().and_then(|meta| match meta {
    Meta::NameValue(ref val) if val.ident == "doc" => Some(val.clone()),
    _ => None,
})

@H2CO3
Copy link
Owner

H2CO3 commented Jul 25, 2018

Thanks for taking the time to work on this! Awesome! 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants