1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
use super::*; use std::iter::FromIterator; pub struct Gen<'a> { relation: GenRelation, tree: &'a TypeTree, } pub enum GenRelation { Absolute, Relative(&'static str), } impl<'a> Gen<'a> { pub fn relative(namespace: &'static str, tree: &'a TypeTree) -> Self { Self { relation: GenRelation::Relative(namespace), tree, } } pub fn absolute(tree: &'a TypeTree) -> Self { Self { relation: GenRelation::Absolute, tree, } } pub fn include_method(&self, signature: &MethodSignature) -> bool { if let GenRelation::Absolute = self.relation { return true; } self.tree.include_method(signature) } pub fn namespace(&self, namespace: &str) -> TokenStream { match self.relation { GenRelation::Absolute => { let mut tokens = TokenStream::new(); for namespace in namespace.split('.') { let namespace = to_ident(namespace); tokens.combine("e! { #namespace:: }); } tokens } GenRelation::Relative(relative) => { if namespace == relative { return TokenStream::new(); } let mut tokens = Vec::new(); let mut relative = relative.split('.').peekable(); let mut namespace = namespace.split('.').peekable(); while relative.peek() == namespace.peek() { if relative.next().is_none() { break; } namespace.next(); } let count = relative.count(); if count > 0 { tokens.resize(tokens.len() + count, quote! { super:: }); } tokens.extend(namespace.map(|namespace| { let namespace = to_ident(namespace); quote! { #namespace:: } })); TokenStream::from_iter(tokens) } } } } #[cfg(test)] mod tests { use super::*; #[test] fn test_namespace() { let reader = TypeReader::get(); let t = reader.resolve_type("Windows.Foundation", "IStringable"); assert_eq!( t.gen_name(&Gen::absolute(&TypeTree::from_namespace(""))) .as_str(), "Windows :: Foundation :: IStringable" ); assert_eq!( t.gen_name(&Gen::relative("Windows", &TypeTree::from_namespace(""))) .as_str(), "Foundation :: IStringable" ); assert_eq!( t.gen_name(&Gen::relative( "Windows.Foundation", &TypeTree::from_namespace("") )) .as_str(), "IStringable" ); assert_eq!( t.gen_name(&Gen::relative( "Windows.Foundation.Collections", &TypeTree::from_namespace("") )) .as_str(), "super :: IStringable" ); } }