/// Return a token-tree for the default "body" - the part after the name that contains the values. /// That is, the `{ ... }` part for structs, the `(...)` part for tuples, and nothing for units. fn default_body_tt(body: &syn::Fields) -> Result<(TokenStream, String), Error> { letmut doc = String::new(); use std::fmt::Write; let body_tt = match body {
syn::Fields::Named(ref fields) => {
doc.push_str(" {"); let result = { let field_assignments = fields
.named
.iter()
.map(|field| { let field_name = field.ident.as_ref(); let (default_value, default_doc) = field_default_expr_and_doc(field)?;
write!(
&mut doc, "\n {}: {},",
field_name.expect("field value in struct is empty"),
default_doc
)
.unwrap(); // let default_value = default_value.into_token_stream();
Ok(quote! { #field_name : #default_value })
})
.collect::<Result<Vec<_>, Error>>()?;
quote! {
{ #(#field_assignments ),*
}
}
}; if doc.ends_with(',') {
doc.pop();
doc.push('\n');
};
doc.push('}');
result
}
syn::Fields::Unnamed(ref fields) => {
doc.push('('); let result = { let field_assignments = fields
.unnamed
.iter()
.map(|field| { let (default_value, default_doc) = field_default_expr_and_doc(field)?;
write!(&mut doc, "{}, ", default_doc).unwrap();
Ok(default_value)
})
.collect::<Result<Vec<TokenStream>, Error>>()?;
quote! {
( #(#field_assignments ),*
)
}
}; if doc.ends_with(", ") {
doc.pop();
doc.pop();
};
doc.push(')');
result
}
&syn::Fields::Unit => quote! {},
};
Ok((body_tt, doc))
}
/// Return a default expression for a field based on it's `#[default = "..."]` attribute. Panic /// if there is more than one, of if there is a `#[default]` attribute without value. fn field_default_expr_and_doc(field: &syn::Field) -> Result<(TokenStream, String), Error> { iflet Some(default_attr) = DefaultAttr::find_in_attributes(&field.attrs)? { let conversion_strategy = default_attr.conversion_strategy(); let field_value = default_attr.code.ok_or_else(|| {
Error::new(field.span(), "Expected #[default = ...] or #[default(...)]")
})?;
let field_value = match conversion_strategy {
ConversionStrategy::NoConversion => field_value,
ConversionStrategy::Into => quote!((#field_value).into()),
};
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.