despatma_lib/
simple_type.rs

1use proc_macro2::TokenStream;
2use quote::ToTokens;
3use syn::parse::{Parse, ParseStream, Result};
4use syn::{Ident, Token};
5
6/// Holds a simple type that is optionally annotated as `dyn`.
7///
8/// The following is an example of its input stream:
9/// ```text
10/// dyn SomeType
11/// ```
12///
13/// The `dyn` keyword is optional.
14#[cfg_attr(any(test, feature = "extra-traits"), derive(Eq, PartialEq, Debug))]
15pub struct SimpleType {
16    pub dyn_token: Option<Token![dyn]>,
17    pub ident: Ident,
18}
19
20/// Make SimpleType parsable from token stream
21impl Parse for SimpleType {
22    fn parse(input: ParseStream) -> Result<Self> {
23        Ok(SimpleType {
24            dyn_token: input.parse()?,
25            ident: input.parse()?,
26        })
27    }
28}
29
30/// Turn SimpleType back into a token stream
31impl ToTokens for SimpleType {
32    fn to_tokens(&self, tokens: &mut TokenStream) {
33        self.dyn_token.to_tokens(tokens);
34        self.ident.to_tokens(tokens);
35    }
36}
37
38#[cfg(test)]
39mod tests {
40    use super::*;
41    use pretty_assertions::assert_eq;
42    use quote::quote;
43    use syn::parse_str;
44
45    type Result = std::result::Result<(), Box<dyn std::error::Error>>;
46
47    #[test]
48    fn parse() -> Result {
49        let actual: SimpleType = parse_str("dyn Button")?;
50        let expected = SimpleType {
51            dyn_token: Some(Default::default()),
52            ident: parse_str("Button")?,
53        };
54
55        assert_eq!(actual, expected);
56        Ok(())
57    }
58
59    #[test]
60    fn parse_without_dyn() -> Result {
61        let actual: SimpleType = parse_str("Button")?;
62        let expected = SimpleType {
63            dyn_token: None,
64            ident: parse_str("Button")?,
65        };
66
67        assert_eq!(actual, expected);
68        Ok(())
69    }
70
71    #[test]
72    #[should_panic(expected = "expected identifier")]
73    fn missing_type() {
74        parse_str::<SimpleType>("dyn").unwrap();
75    }
76
77    #[test]
78    fn to_tokens() -> Result {
79        let input = SimpleType {
80            dyn_token: Some(Default::default()),
81            ident: parse_str("Button")?,
82        };
83        let actual = quote! { #input };
84        let expected: TokenStream = parse_str("dyn Button")?;
85
86        assert_eq!(format!("{}", actual), format!("{}", expected));
87        Ok(())
88    }
89}