add doctest
This commit is contained in:
parent
29d466906f
commit
f5935b673b
47
src/lib.rs
47
src/lib.rs
@ -1,8 +1,11 @@
|
|||||||
|
//! This crate creates `miniconf::Tree` implementations fields in a struct. These carry some extra
|
||||||
|
//! extra information about the field.
|
||||||
|
|
||||||
use std::iter::once;
|
use std::iter::once;
|
||||||
|
|
||||||
use convert_case::{Case, Casing};
|
use convert_case::{Case, Casing};
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
use proc_macro2::{Span as Span2, TokenStream as TokenStream2};
|
use proc_macro2::{Span as Span2, TokenStream as TokenStream2, TokenTree as TokenTree2};
|
||||||
use quote::{format_ident, quote, ToTokens};
|
use quote::{format_ident, quote, ToTokens};
|
||||||
use syn::{
|
use syn::{
|
||||||
parse_macro_input, parse_quote, Attribute, DataStruct, DeriveInput, Expr, ExprLit, Field,
|
parse_macro_input, parse_quote, Attribute, DataStruct, DeriveInput, Expr, ExprLit, Field,
|
||||||
@ -12,6 +15,20 @@ use syn::{
|
|||||||
/// Creates structs for the values to extend them with extra metadata.
|
/// Creates structs for the values to extend them with extra metadata.
|
||||||
///
|
///
|
||||||
/// supported metadata is `min`, `max` and `default`. Doc comments are parsed as `description`
|
/// supported metadata is `min`, `max` and `default`. Doc comments are parsed as `description`
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
/// ```
|
||||||
|
/// use macroconf::config;
|
||||||
|
///
|
||||||
|
/// #[config]
|
||||||
|
/// struct Config {
|
||||||
|
/// /// This will be parsed as description
|
||||||
|
/// #[min] // This will use i32::MIN for the minimum
|
||||||
|
/// #[max = 50] // The value 50 is used for the maximum
|
||||||
|
/// #[default = 42] // A `Default` implementation will be generated returning 42
|
||||||
|
/// field1: i32,
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
#[proc_macro_attribute]
|
#[proc_macro_attribute]
|
||||||
pub fn config(_attr: TokenStream, item: TokenStream) -> TokenStream {
|
pub fn config(_attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||||
let mut input = parse_macro_input!(item as DeriveInput);
|
let mut input = parse_macro_input!(item as DeriveInput);
|
||||||
@ -37,6 +54,32 @@ pub fn config(_attr: TokenStream, item: TokenStream) -> TokenStream {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(attr) = input
|
||||||
|
.attrs
|
||||||
|
.iter_mut()
|
||||||
|
.find(|attr| attr.path().is_ident("derive"))
|
||||||
|
{
|
||||||
|
if let Ok(meta) = attr.meta.require_list() {
|
||||||
|
let derives_tree = meta
|
||||||
|
.tokens
|
||||||
|
.clone()
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|token| match token {
|
||||||
|
TokenTree2::Ident(ident) if ident == Ident::new("Tree", ident.span()) => {
|
||||||
|
Some(ident)
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.count()
|
||||||
|
== 1;
|
||||||
|
if !derives_tree {
|
||||||
|
input.attrs.push(parse_quote!(#[derive(::miniconf::Tree)]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
input.attrs.push(parse_quote!(#[derive(::miniconf::Tree)]));
|
||||||
|
}
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
#input
|
#input
|
||||||
#(#new_types)*
|
#(#new_types)*
|
||||||
@ -339,7 +382,7 @@ fn generate_serde(ident: &Ident, ty: &Type, checked_new: bool) -> TokenStream2 {
|
|||||||
let conversion = if checked_new {
|
let conversion = if checked_new {
|
||||||
quote! {
|
quote! {
|
||||||
Self::new(value).ok_or_else(|| {
|
Self::new(value).ok_or_else(|| {
|
||||||
D::Error::custom("checking value bounds")
|
<D::Error as ::serde::de::Error>::custom("checking value bounds")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user