use syn::token;
use super::helpers::ident;
use super::{ToSyn, ToSynError};
use crate::pure::ast::{PureItem, PureUse, PureUseTree};
impl ToSyn for PureItem {
type Output = syn::Item;
fn to_syn(&self) -> Result<syn::Item, ToSynError> {
Ok(match self {
PureItem::Use(u) => syn::Item::Use(u.to_syn()?),
PureItem::Fn(f) => syn::Item::Fn(f.to_syn()?),
PureItem::Struct(s) => syn::Item::Struct(s.to_syn()?),
PureItem::Enum(e) => syn::Item::Enum(e.to_syn()?),
PureItem::Impl(i) => syn::Item::Impl(i.to_syn()?),
PureItem::Const(c) => syn::Item::Const(c.to_syn()?),
PureItem::Static(s) => syn::Item::Static(s.to_syn()?),
PureItem::Type(t) => syn::Item::Type(t.to_syn()?),
PureItem::Mod(m) => syn::Item::Mod(m.to_syn()?),
PureItem::Trait(t) => syn::Item::Trait(t.to_syn()?),
PureItem::Macro(m) => syn::Item::Macro(m.to_syn()?),
PureItem::Other(s) => syn::parse_str(s).map_err(|e| ToSynError::Other {
message: format!("Failed to parse item '{}': {}", s, e),
})?,
})
}
}
impl ToSyn for PureUse {
type Output = syn::ItemUse;
fn to_syn(&self) -> Result<syn::ItemUse, ToSynError> {
Ok(syn::ItemUse {
attrs: vec![],
vis: self.vis.to_syn()?,
use_token: token::Use::default(),
leading_colon: None,
tree: self.tree.to_syn()?,
semi_token: token::Semi::default(),
})
}
}
impl ToSyn for PureUseTree {
type Output = syn::UseTree;
fn to_syn(&self) -> Result<syn::UseTree, ToSynError> {
Ok(match self {
PureUseTree::Path { path, tree } => syn::UseTree::Path(syn::UsePath {
ident: ident(path),
colon2_token: token::PathSep::default(),
tree: Box::new(tree.to_syn()?),
}),
PureUseTree::Name(name) => syn::UseTree::Name(syn::UseName { ident: ident(name) }),
PureUseTree::Rename { name, rename } => syn::UseTree::Rename(syn::UseRename {
ident: ident(name),
as_token: token::As::default(),
rename: ident(rename),
}),
PureUseTree::Glob => syn::UseTree::Glob(syn::UseGlob {
star_token: token::Star::default(),
}),
PureUseTree::Group(items) => syn::UseTree::Group(syn::UseGroup {
brace_token: token::Brace::default(),
items: items.iter().map(|t| t.to_syn()).collect::<Result<_, _>>()?,
}),
})
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::pure::ast::PureVis;
use quote::ToTokens;
#[test]
fn test_pure_use_simple() {
let use_stmt = PureUse {
vis: PureVis::Private,
tree: PureUseTree::Path {
path: "std".to_string(),
tree: Box::new(PureUseTree::Name("io".to_string())),
},
};
let syn_use = use_stmt.to_syn().unwrap();
let output = syn_use.to_token_stream().to_string();
assert!(output.contains("std"), "Output: {}", output);
assert!(output.contains("io"), "Output: {}", output);
}
#[test]
fn test_pure_use_glob() {
let use_stmt = PureUse {
vis: PureVis::Public,
tree: PureUseTree::Path {
path: "std".to_string(),
tree: Box::new(PureUseTree::Glob),
},
};
let syn_use = use_stmt.to_syn().unwrap();
let output = syn_use.to_token_stream().to_string();
assert!(output.contains("pub"), "Output: {}", output);
assert!(output.contains("*"), "Output: {}", output);
}
#[test]
fn test_pure_use_group() {
let use_stmt = PureUse {
vis: PureVis::Private,
tree: PureUseTree::Path {
path: "std".to_string(),
tree: Box::new(PureUseTree::Group(vec![
PureUseTree::Name("io".to_string()),
PureUseTree::Name("fs".to_string()),
])),
},
};
let syn_use = use_stmt.to_syn().unwrap();
let output = syn_use.to_token_stream().to_string();
assert!(output.contains("io"), "Output: {}", output);
assert!(output.contains("fs"), "Output: {}", output);
}
}