ryo_source/pure/to_syn/
item.rs1use 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}