1fad3a1d3Sopenharmony_ci#![allow(clippy::uninlined_format_args)] 2fad3a1d3Sopenharmony_ci 3fad3a1d3Sopenharmony_ci#[macro_use] 4fad3a1d3Sopenharmony_cimod macros; 5fad3a1d3Sopenharmony_ci 6fad3a1d3Sopenharmony_ciuse proc_macro2::{Delimiter, Group, Ident, Punct, Spacing, Span, TokenStream, TokenTree}; 7fad3a1d3Sopenharmony_ciuse syn::parse::{Parse, ParseStream}; 8fad3a1d3Sopenharmony_ciuse syn::{DeriveInput, Result, Visibility}; 9fad3a1d3Sopenharmony_ci 10fad3a1d3Sopenharmony_ci#[derive(Debug)] 11fad3a1d3Sopenharmony_cistruct VisRest { 12fad3a1d3Sopenharmony_ci vis: Visibility, 13fad3a1d3Sopenharmony_ci rest: TokenStream, 14fad3a1d3Sopenharmony_ci} 15fad3a1d3Sopenharmony_ci 16fad3a1d3Sopenharmony_ciimpl Parse for VisRest { 17fad3a1d3Sopenharmony_ci fn parse(input: ParseStream) -> Result<Self> { 18fad3a1d3Sopenharmony_ci Ok(VisRest { 19fad3a1d3Sopenharmony_ci vis: input.parse()?, 20fad3a1d3Sopenharmony_ci rest: input.parse()?, 21fad3a1d3Sopenharmony_ci }) 22fad3a1d3Sopenharmony_ci } 23fad3a1d3Sopenharmony_ci} 24fad3a1d3Sopenharmony_ci 25fad3a1d3Sopenharmony_cimacro_rules! assert_vis_parse { 26fad3a1d3Sopenharmony_ci ($input:expr, Ok($p:pat)) => { 27fad3a1d3Sopenharmony_ci assert_vis_parse!($input, Ok($p) + ""); 28fad3a1d3Sopenharmony_ci }; 29fad3a1d3Sopenharmony_ci 30fad3a1d3Sopenharmony_ci ($input:expr, Ok($p:pat) + $rest:expr) => { 31fad3a1d3Sopenharmony_ci let expected = $rest.parse::<TokenStream>().unwrap(); 32fad3a1d3Sopenharmony_ci let parse: VisRest = syn::parse_str($input).unwrap(); 33fad3a1d3Sopenharmony_ci 34fad3a1d3Sopenharmony_ci match parse.vis { 35fad3a1d3Sopenharmony_ci $p => {} 36fad3a1d3Sopenharmony_ci _ => panic!("Expected {}, got {:?}", stringify!($p), parse.vis), 37fad3a1d3Sopenharmony_ci } 38fad3a1d3Sopenharmony_ci 39fad3a1d3Sopenharmony_ci // NOTE: Round-trips through `to_string` to avoid potential whitespace 40fad3a1d3Sopenharmony_ci // diffs. 41fad3a1d3Sopenharmony_ci assert_eq!(parse.rest.to_string(), expected.to_string()); 42fad3a1d3Sopenharmony_ci }; 43fad3a1d3Sopenharmony_ci 44fad3a1d3Sopenharmony_ci ($input:expr, Err) => { 45fad3a1d3Sopenharmony_ci syn::parse2::<VisRest>($input.parse().unwrap()).unwrap_err(); 46fad3a1d3Sopenharmony_ci }; 47fad3a1d3Sopenharmony_ci} 48fad3a1d3Sopenharmony_ci 49fad3a1d3Sopenharmony_ci#[test] 50fad3a1d3Sopenharmony_cifn test_pub() { 51fad3a1d3Sopenharmony_ci assert_vis_parse!("pub", Ok(Visibility::Public(_))); 52fad3a1d3Sopenharmony_ci} 53fad3a1d3Sopenharmony_ci 54fad3a1d3Sopenharmony_ci#[test] 55fad3a1d3Sopenharmony_cifn test_inherited() { 56fad3a1d3Sopenharmony_ci assert_vis_parse!("", Ok(Visibility::Inherited)); 57fad3a1d3Sopenharmony_ci} 58fad3a1d3Sopenharmony_ci 59fad3a1d3Sopenharmony_ci#[test] 60fad3a1d3Sopenharmony_cifn test_in() { 61fad3a1d3Sopenharmony_ci assert_vis_parse!("pub(in foo::bar)", Ok(Visibility::Restricted(_))); 62fad3a1d3Sopenharmony_ci} 63fad3a1d3Sopenharmony_ci 64fad3a1d3Sopenharmony_ci#[test] 65fad3a1d3Sopenharmony_cifn test_pub_crate() { 66fad3a1d3Sopenharmony_ci assert_vis_parse!("pub(crate)", Ok(Visibility::Restricted(_))); 67fad3a1d3Sopenharmony_ci} 68fad3a1d3Sopenharmony_ci 69fad3a1d3Sopenharmony_ci#[test] 70fad3a1d3Sopenharmony_cifn test_pub_self() { 71fad3a1d3Sopenharmony_ci assert_vis_parse!("pub(self)", Ok(Visibility::Restricted(_))); 72fad3a1d3Sopenharmony_ci} 73fad3a1d3Sopenharmony_ci 74fad3a1d3Sopenharmony_ci#[test] 75fad3a1d3Sopenharmony_cifn test_pub_super() { 76fad3a1d3Sopenharmony_ci assert_vis_parse!("pub(super)", Ok(Visibility::Restricted(_))); 77fad3a1d3Sopenharmony_ci} 78fad3a1d3Sopenharmony_ci 79fad3a1d3Sopenharmony_ci#[test] 80fad3a1d3Sopenharmony_cifn test_missing_in() { 81fad3a1d3Sopenharmony_ci assert_vis_parse!("pub(foo::bar)", Ok(Visibility::Public(_)) + "(foo::bar)"); 82fad3a1d3Sopenharmony_ci} 83fad3a1d3Sopenharmony_ci 84fad3a1d3Sopenharmony_ci#[test] 85fad3a1d3Sopenharmony_cifn test_missing_in_path() { 86fad3a1d3Sopenharmony_ci assert_vis_parse!("pub(in)", Err); 87fad3a1d3Sopenharmony_ci} 88fad3a1d3Sopenharmony_ci 89fad3a1d3Sopenharmony_ci#[test] 90fad3a1d3Sopenharmony_cifn test_crate_path() { 91fad3a1d3Sopenharmony_ci assert_vis_parse!( 92fad3a1d3Sopenharmony_ci "pub(crate::A, crate::B)", 93fad3a1d3Sopenharmony_ci Ok(Visibility::Public(_)) + "(crate::A, crate::B)" 94fad3a1d3Sopenharmony_ci ); 95fad3a1d3Sopenharmony_ci} 96fad3a1d3Sopenharmony_ci 97fad3a1d3Sopenharmony_ci#[test] 98fad3a1d3Sopenharmony_cifn test_junk_after_in() { 99fad3a1d3Sopenharmony_ci assert_vis_parse!("pub(in some::path @@garbage)", Err); 100fad3a1d3Sopenharmony_ci} 101fad3a1d3Sopenharmony_ci 102fad3a1d3Sopenharmony_ci#[test] 103fad3a1d3Sopenharmony_cifn test_empty_group_vis() { 104fad3a1d3Sopenharmony_ci // mimics `struct S { $vis $field: () }` where $vis is empty 105fad3a1d3Sopenharmony_ci let tokens = TokenStream::from_iter(vec![ 106fad3a1d3Sopenharmony_ci TokenTree::Ident(Ident::new("struct", Span::call_site())), 107fad3a1d3Sopenharmony_ci TokenTree::Ident(Ident::new("S", Span::call_site())), 108fad3a1d3Sopenharmony_ci TokenTree::Group(Group::new( 109fad3a1d3Sopenharmony_ci Delimiter::Brace, 110fad3a1d3Sopenharmony_ci TokenStream::from_iter(vec![ 111fad3a1d3Sopenharmony_ci TokenTree::Group(Group::new(Delimiter::None, TokenStream::new())), 112fad3a1d3Sopenharmony_ci TokenTree::Group(Group::new( 113fad3a1d3Sopenharmony_ci Delimiter::None, 114fad3a1d3Sopenharmony_ci TokenStream::from_iter(vec![TokenTree::Ident(Ident::new( 115fad3a1d3Sopenharmony_ci "f", 116fad3a1d3Sopenharmony_ci Span::call_site(), 117fad3a1d3Sopenharmony_ci ))]), 118fad3a1d3Sopenharmony_ci )), 119fad3a1d3Sopenharmony_ci TokenTree::Punct(Punct::new(':', Spacing::Alone)), 120fad3a1d3Sopenharmony_ci TokenTree::Group(Group::new(Delimiter::Parenthesis, TokenStream::new())), 121fad3a1d3Sopenharmony_ci ]), 122fad3a1d3Sopenharmony_ci )), 123fad3a1d3Sopenharmony_ci ]); 124fad3a1d3Sopenharmony_ci 125fad3a1d3Sopenharmony_ci snapshot!(tokens as DeriveInput, @r###" 126fad3a1d3Sopenharmony_ci DeriveInput { 127fad3a1d3Sopenharmony_ci vis: Visibility::Inherited, 128fad3a1d3Sopenharmony_ci ident: "S", 129fad3a1d3Sopenharmony_ci generics: Generics, 130fad3a1d3Sopenharmony_ci data: Data::Struct { 131fad3a1d3Sopenharmony_ci fields: Fields::Named { 132fad3a1d3Sopenharmony_ci named: [ 133fad3a1d3Sopenharmony_ci Field { 134fad3a1d3Sopenharmony_ci vis: Visibility::Inherited, 135fad3a1d3Sopenharmony_ci ident: Some("f"), 136fad3a1d3Sopenharmony_ci colon_token: Some, 137fad3a1d3Sopenharmony_ci ty: Type::Tuple, 138fad3a1d3Sopenharmony_ci }, 139fad3a1d3Sopenharmony_ci ], 140fad3a1d3Sopenharmony_ci }, 141fad3a1d3Sopenharmony_ci }, 142fad3a1d3Sopenharmony_ci } 143fad3a1d3Sopenharmony_ci "###); 144fad3a1d3Sopenharmony_ci} 145