Skip to main content

ryo_source/pure/to_syn/
item.rs

1//! ToSyn implementations for items and use statements.
2
3use syn::token;
4
5use super::helpers::ident;
6use super::{ToSyn, ToSynError};
7use crate::pure::ast::{PureItem, PureUse, PureUseTree};
8
9impl ToSyn for PureItem {
10    type Output = syn::Item;
11
12    fn to_syn(&self) -> Result<syn::Item, ToSynError> {
13        Ok(match self {
14            PureItem::Use(u) => syn::Item::Use(u.to_syn()?),
15            PureItem::Fn(f) => syn::Item::Fn(f.to_syn()?),
16            PureItem::Struct(s) => syn::Item::Struct(s.to_syn()?),
17            PureItem::Enum(e) => syn::Item::Enum(e.to_syn()?),
18            PureItem::Impl(i) => syn::Item::Impl(i.to_syn()?),
19            PureItem::Const(c) => syn::Item::Const(c.to_syn()?),
20            PureItem::Static(s) => syn::Item::Static(s.to_syn()?),
21            PureItem::Type(t) => syn::Item::Type(t.to_syn()?),
22            PureItem::Mod(m) => syn::Item::Mod(m.to_syn()?),
23            PureItem::Trait(t) => syn::Item::Trait(t.to_syn()?),
24            PureItem::Macro(m) => syn::Item::Macro(m.to_syn()?),
25            PureItem::Other(s) => syn::parse_str(s).map_err(|e| ToSynError::Other {
26                message: format!("Failed to parse item '{}': {}", s, e),
27            })?,
28        })
29    }
30}
31
32impl ToSyn for PureUse {
33    type Output = syn::ItemUse;
34
35    fn to_syn(&self) -> Result<syn::ItemUse, ToSynError> {
36        Ok(syn::ItemUse {
37            attrs: vec![],
38            vis: self.vis.to_syn()?,
39            use_token: token::Use::default(),
40            leading_colon: None,
41            tree: self.tree.to_syn()?,
42            semi_token: token::Semi::default(),
43        })
44    }
45}
46
47impl ToSyn for PureUseTree {
48    type Output = syn::UseTree;
49
50    fn to_syn(&self) -> Result<syn::UseTree, ToSynError> {
51        Ok(match self {
52            PureUseTree::Path { path, tree } => syn::UseTree::Path(syn::UsePath {
53                ident: ident(path),
54                colon2_token: token::PathSep::default(),
55                tree: Box::new(tree.to_syn()?),
56            }),
57            PureUseTree::Name(name) => syn::UseTree::Name(syn::UseName { ident: ident(name) }),
58            PureUseTree::Rename { name, rename } => syn::UseTree::Rename(syn::UseRename {
59                ident: ident(name),
60                as_token: token::As::default(),
61                rename: ident(rename),
62            }),
63            PureUseTree::Glob => syn::UseTree::Glob(syn::UseGlob {
64                star_token: token::Star::default(),
65            }),
66            PureUseTree::Group(items) => syn::UseTree::Group(syn::UseGroup {
67                brace_token: token::Brace::default(),
68                items: items.iter().map(|t| t.to_syn()).collect::<Result<_, _>>()?,
69            }),
70        })
71    }
72}
73
74#[cfg(test)]
75mod tests {
76    use super::*;
77    use crate::pure::ast::PureVis;
78    use quote::ToTokens;
79
80    #[test]
81    fn test_pure_use_simple() {
82        let use_stmt = PureUse {
83            vis: PureVis::Private,
84            tree: PureUseTree::Path {
85                path: "std".to_string(),
86                tree: Box::new(PureUseTree::Name("io".to_string())),
87            },
88        };
89        let syn_use = use_stmt.to_syn().unwrap();
90        let output = syn_use.to_token_stream().to_string();
91        assert!(output.contains("std"), "Output: {}", output);
92        assert!(output.contains("io"), "Output: {}", output);
93    }
94
95    #[test]
96    fn test_pure_use_glob() {
97        let use_stmt = PureUse {
98            vis: PureVis::Public,
99            tree: PureUseTree::Path {
100                path: "std".to_string(),
101                tree: Box::new(PureUseTree::Glob),
102            },
103        };
104        let syn_use = use_stmt.to_syn().unwrap();
105        let output = syn_use.to_token_stream().to_string();
106        assert!(output.contains("pub"), "Output: {}", output);
107        assert!(output.contains("*"), "Output: {}", output);
108    }
109
110    #[test]
111    fn test_pure_use_group() {
112        let use_stmt = PureUse {
113            vis: PureVis::Private,
114            tree: PureUseTree::Path {
115                path: "std".to_string(),
116                tree: Box::new(PureUseTree::Group(vec![
117                    PureUseTree::Name("io".to_string()),
118                    PureUseTree::Name("fs".to_string()),
119                ])),
120            },
121        };
122        let syn_use = use_stmt.to_syn().unwrap();
123        let output = syn_use.to_token_stream().to_string();
124        assert!(output.contains("io"), "Output: {}", output);
125        assert!(output.contains("fs"), "Output: {}", output);
126    }
127}