Skip to content

Commit

Permalink
Update syn in pdf_derive from version 1 to 2.
Browse files Browse the repository at this point in the history
  • Loading branch information
mwanner authored and s3bk committed Jun 22, 2024
1 parent c548131 commit a9087fa
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 61 deletions.
2 changes: 1 addition & 1 deletion pdf_derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ license = "MIT"
edition = "2018"

[dependencies]
syn = { version = "1", features = ["full", "extra-traits"] }
syn = { version = "2", features = ["full", "extra-traits"] }
proc-macro2 = "1.0.24"
quote = "1"

Expand Down
141 changes: 81 additions & 60 deletions pdf_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ extern crate quote;

use proc_macro::{TokenStream};
use proc_macro2::{TokenStream as TokenStream2, Span};
use syn::{*, punctuated::Punctuated, token::Where};
use syn::*;
type SynStream = TokenStream2;

// Debugging:
Expand Down Expand Up @@ -163,31 +163,43 @@ impl FieldAttrs {
}
fn parse(list: &[Attribute]) -> FieldAttrs {
let mut attrs = FieldAttrs::new();
for attr in list.iter().filter(|attr| attr.path.is_ident("pdf")) {
let list = match attr.parse_meta() {
Ok(Meta::List(list)) => list,
Ok(_) => panic!("only #[pdf(attrs...)] is allowed"),
Err(e) => panic!("can't parse meta attributes: {}", e)
};
for meta in list.nested.iter() {
match *meta {
NestedMeta::Meta(Meta::NameValue(MetaNameValue { ref path, lit: Lit::Str(ref value), ..})) => {
if path.is_ident("key") {
attrs.key = Some(value.clone());
} else if path.is_ident("default") {
attrs.default = Some(value.clone());
} else if path.is_ident("name") {
attrs.name = Some(value.clone());
} else {
panic!("unsupported key {}", path.segments.iter().map(|s| s.ident.to_string()).collect::<Vec<String>>().join("::"))
}
},
NestedMeta::Meta(Meta::Path(ref path)) if path.is_ident("skip") => attrs.skip = true,
NestedMeta::Meta(Meta::Path(ref path)) if path.is_ident("other") => attrs.other = true,
NestedMeta::Meta(Meta::Path(ref path)) if path.is_ident("indirect") => attrs.indirect = true,
_ => panic!(r#"Derive error - Supported derive attributes: `key="Key"`, `default="some code", skip, other, indirect`."#)
for attr in list.iter().filter(|attr| attr.path().is_ident("pdf")) {
attr.parse_nested_meta(|meta| {
if meta.path.is_ident("key") {
let value = meta.value()?;
attrs.key = Some(value.parse()?);
return Ok(());
}
}

if meta.path.is_ident("default") {
let value = meta.value()?;
attrs.default = Some(value.parse()?);
return Ok(());
}

if meta.path.is_ident("name") {
let value = meta.value()?;
attrs.name = Some(value.parse()?);
return Ok(());
}

if meta.path.is_ident("skip") {
attrs.skip = true;
return Ok(());
}

if meta.path.is_ident("other") {
attrs.other = true;
return Ok(());
}

if meta.path.is_ident("indirect") {
attrs.indirect = true;
return Ok(());
}

Err(meta.error("unsupported key"))
}).expect("parse error");
}
attrs
}
Expand All @@ -209,42 +221,51 @@ impl GlobalAttrs {
fn from_ast(ast: &DeriveInput) -> GlobalAttrs {
let mut attrs = GlobalAttrs::default();

for attr in ast.attrs.iter().filter(|attr| attr.path.is_ident("pdf")) {
let list = match attr.parse_meta() {
Ok(Meta::List(list)) => list,
Ok(_) => panic!("only #[pdf(attrs...)] is allowed"),
Err(e) => panic!("can't parse meta attributes: {}", e)
};
for attr in ast.attrs.iter().filter(|attr| attr.path().is_ident("pdf")) {
attr.parse_nested_meta(|meta| {
if meta.path.is_ident("Type") {
let value = meta.value()?;
let lit = value.parse()?;
match lit {
Lit::Str(ref value) => {
let mut value = value.value();
attrs.type_required = if value.ends_with('?') {
value.pop(); // remove '?'
false
} else {
true
};
attrs.type_name = Some(value);
},
_ => panic!("Value of 'Type' attribute must be a String."),
};
return Ok(())
}

// Loop through list of attributes
for meta in list.nested.iter() {
match *meta {
NestedMeta::Meta(Meta::NameValue(MetaNameValue { ref path, ref lit, ..})) => {
if path.is_ident("Type") {
match lit {
Lit::Str(ref value) => {
let mut value = value.value();
attrs.type_required = if value.ends_with('?') {
value.pop(); // remove '?'
false
} else {
true
};
attrs.type_name = Some(value);
},
_ => panic!("Value of 'Type' attribute must be a String."),
}
} else {
match lit {
Lit::Str(ref value) => attrs.checks.push((path.segments.iter().map(|s| s.ident.to_string()).collect::<Vec<String>>().join("::"), value.value())),
_ => panic!("Other checks must have RHS String."),
}
if meta.path.is_ident("is_stream") {
attrs.is_stream = true;
return Ok(())
}

if let Ok(value) = meta.value() {
let path = &meta.path;
let lit = value.parse()?;
match lit {
Lit::Str(ref value) => {
let segments = path.segments
.iter()
.map(|s| s.ident.to_string())
.collect::<Vec<String>>()
.join("::");
attrs.checks.push((segments, value.value()));
}
},
NestedMeta::Meta(Meta::Path(ref path)) if path.is_ident("is_stream") => attrs.is_stream = true,
_ => {}
_ => panic!("Other checks must have RHS String."),
};
return Ok(())
}
}

Ok(())
}).expect("error with global attrs parsing");
}

attrs
Expand Down Expand Up @@ -322,9 +343,9 @@ fn impl_object_for_enum(ast: &DeriveInput, data: &DataEnum) -> SynStream {
assert_eq!(int_count, data.variants.len(), "either none or all variants can have a descriminant");

let parts = data.variants.iter().map(|var| {
if let Some((_, ref expr)) = var.discriminant {
if let Some((_, Expr::Lit(ref lit_expr))) = var.discriminant {
let var_ident = &var.ident;
let pat = Pat::Lit(PatLit { expr: Box::new(expr.clone()), attrs: vec![] });
let pat = Pat::from(lit_expr.clone());
quote! {
#pat => Ok(#id::#var_ident)
}
Expand Down

0 comments on commit a9087fa

Please sign in to comment.