blob: 798cbee77384cf698e4f42fc45c3b7a65d60428a [file] [log] [blame]
David Tolnay7db73692019-10-20 14:51:12 -04001use crate::syntax::{Derive, Doc};
2use proc_macro2::Ident;
3use syn::parse::{ParseStream, Parser};
4use syn::{Attribute, Error, LitStr, Path, Result, Token};
5
6pub(super) fn parse_doc(attrs: &[Attribute]) -> Result<Doc> {
7 let mut doc = Doc::new();
8 let derives = None;
9 parse(attrs, &mut doc, derives)?;
10 Ok(doc)
11}
12
13pub(super) fn parse(
14 attrs: &[Attribute],
15 doc: &mut Doc,
David Tolnaye86b9cf2020-05-10 14:24:29 -070016 mut derives: Option<&mut Vec<Derive>>,
David Tolnay7db73692019-10-20 14:51:12 -040017) -> Result<()> {
18 for attr in attrs {
19 if attr.path.is_ident("doc") {
20 let lit = parse_doc_attribute.parse2(attr.tokens.clone())?;
21 doc.push(lit);
22 continue;
23 } else if attr.path.is_ident("derive") {
24 if let Some(derives) = &mut derives {
25 derives.extend(attr.parse_args_with(parse_derive_attribute)?);
26 continue;
27 }
28 }
29 return Err(Error::new_spanned(attr, "unsupported attribute"));
30 }
31 Ok(())
32}
33
34fn parse_doc_attribute(input: ParseStream) -> Result<LitStr> {
35 input.parse::<Token![=]>()?;
36 let lit: LitStr = input.parse()?;
37 Ok(lit)
38}
39
David Tolnaye86b9cf2020-05-10 14:24:29 -070040fn parse_derive_attribute(input: ParseStream) -> Result<Vec<Derive>> {
David Tolnay7db73692019-10-20 14:51:12 -040041 input
42 .parse_terminated::<Path, Token![,]>(Path::parse_mod_style)?
43 .into_iter()
David Tolnaye86b9cf2020-05-10 14:24:29 -070044 .map(|path| {
45 if let Some(ident) = path.get_ident() {
46 if let Some(derive) = Derive::from(ident) {
47 return Ok(derive);
48 }
49 }
50 Err(Error::new_spanned(path, "unsupported derive"))
David Tolnay7db73692019-10-20 14:51:12 -040051 })
52 .collect()
53}
54
55impl Derive {
56 pub fn from(ident: &Ident) -> Option<Self> {
57 match ident.to_string().as_str() {
58 "Clone" => Some(Derive::Clone),
59 "Copy" => Some(Derive::Copy),
60 _ => None,
61 }
62 }
63}
64
65impl AsRef<str> for Derive {
66 fn as_ref(&self) -> &str {
67 match self {
68 Derive::Clone => "Clone",
69 Derive::Copy => "Copy",
70 }
71 }
72}