From 7c390ea17782e93521ac6059906b613fbe7ce9dd Mon Sep 17 00:00:00 2001 From: Trangar Date: Tue, 16 Jan 2024 10:22:05 +0100 Subject: [PATCH] pub incorrectly consuming a field type (#78) * Fixed issue 77; pub incorrectly consuming a field type * Fixed typo in type check * Added specific check for pub(crate | self | super | in) --------- Co-authored-by: Victor Koenders --- src/parse/body.rs | 30 ++++++++++++++++++++++++++++++ src/parse/visibility.rs | 19 +++++++++++++++---- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/src/parse/body.rs b/src/parse/body.rs index 3947c58..d24012b 100644 --- a/src/parse/body.rs +++ b/src/parse/body.rs @@ -127,6 +127,36 @@ fn test_struct_body_take() { } } +#[test] +fn issue_77() { + // https://github.com/bincode-org/virtue/issues/77 + use crate::token_stream; + + let stream = &mut token_stream("struct Test(pub [u8; 32])"); + let (data_type, ident) = super::DataType::take(stream).unwrap(); + assert_eq!(data_type, super::DataType::Struct); + assert_eq!(ident, "Test"); + let body = StructBody::take(stream).unwrap(); + let fields = body.fields.unwrap(); + let Fields::Tuple(t) = fields else { + panic!("Fields is not a tuple") + }; + assert_eq!(t.len(), 1); + assert_eq!(t[0].r#type[0].to_string(), "[u8 ; 32]"); + + let stream = &mut token_stream("struct Foo(pub (u8, ))"); + let (data_type, ident) = super::DataType::take(stream).unwrap(); + assert_eq!(data_type, super::DataType::Struct); + assert_eq!(ident, "Foo"); + let body = StructBody::take(stream).unwrap(); + let fields = body.fields.unwrap(); + let Fields::Tuple(t) = fields else { + panic!("Fields is not a tuple") + }; + assert_eq!(t.len(), 1); + assert_eq!(t[0].r#type[0].to_string(), "(u8 ,)"); +} + /// The body of an enum #[derive(Debug)] pub struct EnumBody { diff --git a/src/parse/visibility.rs b/src/parse/visibility.rs index 77aa39f..5f09050 100644 --- a/src/parse/visibility.rs +++ b/src/parse/visibility.rs @@ -1,5 +1,5 @@ use super::utils::*; -use crate::prelude::TokenTree; +use crate::prelude::{Delimiter, TokenTree}; use crate::Result; use std::iter::Peekable; @@ -21,9 +21,20 @@ impl Visibility { assume_ident(input.next()); // check if the next token is `pub(...)` - if let Some(TokenTree::Group(_)) = input.peek() { - // we just consume the visibility, we're not actually using it for generation - assume_group(input.next()); + if let Some(TokenTree::Group(g)) = input.peek() { + if g.delimiter() == Delimiter::Parenthesis { + // check if this is one of: + // - pub ( crate ) + // - pub ( self ) + // - pub ( super ) + // - pub ( in ... ) + if let Some(TokenTree::Ident(i)) = g.stream().into_iter().next() { + if matches!(i.to_string().as_str(), "crate" | "self" | "super" | "in") { + // it is, ignore this token + assume_group(input.next()); + } + } + } } Ok(Visibility::Pub)