Skip to content

Commit

Permalink
Update syn to version 2
Browse files Browse the repository at this point in the history
  • Loading branch information
Flowneee committed Jul 25, 2024
1 parent 74714de commit 9df21a2
Show file tree
Hide file tree
Showing 8 changed files with 71 additions and 71 deletions.
5 changes: 2 additions & 3 deletions okapi-operation-macro/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,11 @@ proc-macro = true

[dependencies]

darling = "0.14.3"
darling = "0.20.10"
lazy_static = "1"
proc-macro2 = "1"
quote = "1"
# TODO: bump to 2.x
syn = { version = "1", features = ["full"] }
syn = { version = "2", features = ["full"] }
thiserror = "1"

[features]
Expand Down
7 changes: 2 additions & 5 deletions okapi-operation-macro/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![allow(clippy::manual_unwrap_or_default)]

use syn::{parse_macro_input, AttributeArgs, ItemFn};
use syn::{parse_macro_input, ItemFn};

mod error;
mod operation;
Expand All @@ -13,10 +13,7 @@ pub fn openapi(
attr: proc_macro::TokenStream,
input: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
match operation::openapi(
parse_macro_input!(attr as AttributeArgs),
parse_macro_input!(input as ItemFn),
) {
match operation::openapi(attr, parse_macro_input!(input as ItemFn)) {
Ok(x) => x.into(),
Err(err) => err.write().into(),
}
Expand Down
13 changes: 9 additions & 4 deletions okapi-operation-macro/src/operation/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use darling::FromMeta;
use darling::{ast::NestedMeta, FromMeta};
use proc_macro2::{Span, TokenStream};
use quote::{quote, ToTokens};
use syn::{AttributeArgs, Ident, ItemFn, Visibility};
use syn::{Ident, ItemFn, Visibility};

use self::{external_docs::ExternalDocs, request_body::RequestBody, response::Responses};
use crate::{
Expand Down Expand Up @@ -87,9 +87,14 @@ impl ToTokens for OperationAttrs {
}
}

pub(crate) fn openapi(mut attrs: AttributeArgs, mut input: ItemFn) -> Result<TokenStream, Error> {
pub(crate) fn openapi(
attrs: proc_macro::TokenStream,
mut input: ItemFn,
) -> Result<TokenStream, Error> {
let mut attrs = NestedMeta::parse_meta_list(attrs.into())?;

for attr in take_attributes(&mut input.attrs, OPENAPI_ATTRIBUTE_NAME) {
attrs.extend(attribute_to_args(&attr, false)?);
attrs.extend(attribute_to_args(&attr)?);
}
let mut operation_attrs = OperationAttrs::from_list(&attrs)?;
operation_attrs
Expand Down
19 changes: 9 additions & 10 deletions okapi-operation-macro/src/operation/parameters.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use darling::FromMeta;
use proc_macro2::TokenStream;
use quote::{quote, ToTokens};
use syn::Meta;
use syn::{punctuated::Punctuated, Meta, Token};

use super::cookie::{Cookie, COOKIE_ATTRIBUTE_NAME};
use crate::{
Expand All @@ -11,7 +11,7 @@ use crate::{
query::{Query, QUERY_ATTRIBUTE_NAME},
reference::{Reference, REFERENCE_ATTRIBUTE_NAME},
},
utils::{meta_to_meta_list, nested_meta_to_meta},
utils::meta_to_meta_list,
};

// TODO: support cookie parameters
Expand Down Expand Up @@ -58,22 +58,21 @@ impl FromMeta for Parameters {
fn from_meta(meta: &Meta) -> Result<Self, darling::Error> {
let meta_list = meta_to_meta_list(meta)?;
let mut this = Self::default();
for nested_meta in meta_list.nested.iter() {
let meta = nested_meta_to_meta(nested_meta)?;
for meta in meta_list.parse_args_with(Punctuated::<Meta, Token![,]>::parse_terminated)? {
let meta_ident = meta
.path()
.get_ident()
.ok_or_else(|| darling::Error::custom("Should have Ident").with_span(meta))?;
.ok_or_else(|| darling::Error::custom("Should have Ident").with_span(&meta))?;
if meta_ident == HEADER_ATTRIBUTE_NAME {
this.header_parameters.push(Header::from_meta(meta)?);
this.header_parameters.push(Header::from_meta(&meta)?);
} else if meta_ident == PATH_ATTRIBUTE_NAME {
this.path_parameters.push(Path::from_meta(meta)?);
this.path_parameters.push(Path::from_meta(&meta)?);
} else if meta_ident == QUERY_ATTRIBUTE_NAME {
this.query_parameters.push(Query::from_meta(meta)?);
this.query_parameters.push(Query::from_meta(&meta)?);
} else if meta_ident == COOKIE_ATTRIBUTE_NAME {
this.cookie_parameters.push(Cookie::from_meta(meta)?);
this.cookie_parameters.push(Cookie::from_meta(&meta)?);
} else if meta_ident == REFERENCE_ATTRIBUTE_NAME {
this.ref_parameters.push(Reference::from_meta(meta)?);
this.ref_parameters.push(Reference::from_meta(&meta)?);
} else {
return Err(
darling::Error::custom("Unsupported type of parameter").with_span(meta_ident)
Expand Down
4 changes: 2 additions & 2 deletions okapi-operation-macro/src/operation/request_body/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ impl RequestBody {

// Check attributes, removing matching
for attr in pt.attrs.drain(..) {
if attr.path.get_ident().map_or(false, |x| {
if attr.path().get_ident().map_or(false, |x| {
x == REQUEST_BODY_ATTRIBUTE_NAME || x == REQUEST_BODY_ATTRIBUTE_NAME_DEPRECATED
}) {
matched_attrs.push(attr);
Expand All @@ -76,7 +76,7 @@ impl RequestBody {
let Some(attr) = matched_attrs.into_iter().next() else {
return Ok(None);
};
let parsed_attrs = RequestBodyAttrs::from_list(&attribute_to_args(&attr, true)?)?;
let parsed_attrs = RequestBodyAttrs::from_list(&attribute_to_args(&attr)?)?;

Ok(Some(Self {
attrs: parsed_attrs,
Expand Down
28 changes: 14 additions & 14 deletions okapi-operation-macro/src/operation/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@ use std::ops::Deref;

use darling::FromMeta;
use quote::{quote, ToTokens};
use syn::{punctuated::Punctuated, token::Paren, ItemFn, Meta, Path, ReturnType, Type, TypeTuple};
use syn::{
punctuated::Punctuated, token::Paren, ItemFn, Meta, Path, ReturnType, Token, Type, TypeTuple,
};

use crate::{
operation::{
header::{Header, HEADER_ATTRIBUTE_NAME},
reference::{Reference, REFERENCE_ATTRIBUTE_NAME},
},
utils::{meta_to_meta_list, nested_meta_to_meta},
utils::meta_to_meta_list,
};

// TODO: throw error if responses from different sources overlap OR merge them via oneOf
Expand All @@ -28,16 +30,15 @@ impl FromMeta for Headers {
fn from_meta(meta: &Meta) -> Result<Self, darling::Error> {
let meta_list = meta_to_meta_list(meta)?;
let mut this = Self::default();
for nested_meta in meta_list.nested.iter() {
let meta = nested_meta_to_meta(nested_meta)?;
for meta in meta_list.parse_args_with(Punctuated::<Meta, Token![,]>::parse_terminated)? {
let meta_ident = meta
.path()
.get_ident()
.ok_or_else(|| darling::Error::custom("Should have Ident").with_span(meta))?;
.ok_or_else(|| darling::Error::custom("Should have Ident").with_span(&meta))?;
if meta_ident == HEADER_ATTRIBUTE_NAME {
this.headers.push(Header::from_meta(meta)?);
this.headers.push(Header::from_meta(&meta)?);
} else if meta_ident == REFERENCE_ATTRIBUTE_NAME {
this.refs.push(Reference::from_meta(meta)?);
this.refs.push(Reference::from_meta(&meta)?);
} else {
return Err(darling::Error::custom(
"Response's header definition should have 'header' or 'reference' Ident",
Expand Down Expand Up @@ -160,22 +161,21 @@ impl FromMeta for Responses {
fn from_meta(meta: &Meta) -> Result<Self, darling::Error> {
let meta_list = meta_to_meta_list(meta)?;
let mut this = Self::default();
for nested_meta in meta_list.nested.iter() {
let meta = nested_meta_to_meta(nested_meta)?;
for meta in meta_list.parse_args_with(Punctuated::<Meta, Token![,]>::parse_terminated)? {
let meta_ident = meta
.path()
.get_ident()
.ok_or_else(|| darling::Error::custom("Should have Ident").with_span(meta))?;
.ok_or_else(|| darling::Error::custom("Should have Ident").with_span(&meta))?;
if meta_ident == RESPONSE_ATTRIBUTE_NAME {
let parsed = Response::from_meta(meta)?;
let parsed = Response::from_meta(&meta)?;
this.responses.push(parsed);
} else if meta_ident == REFERENCE_ATTRIBUTE_NAME {
let parsed = RefResponse::from_meta(meta)?;
let parsed = RefResponse::from_meta(&meta)?;
this.refs.push(parsed);
} else if meta_ident == IGNORE_RETURN_TYPE_ATTRIBUTE_NAME {
this.ignore_return_type = bool::from_meta(meta)?;
this.ignore_return_type = bool::from_meta(&meta)?;
} else if meta_ident == FROM_TYPE_ATTRIBUTE_NAME {
this.from_type.push(Path::from_meta(meta)?);
this.from_type.push(Path::from_meta(&meta)?);
} else {
return Err(darling::Error::custom(
"Response definition should have 'response', 'reference', 'from_type' or 'ignore_return_type' Ident",
Expand Down
32 changes: 21 additions & 11 deletions okapi-operation-macro/src/operation/security.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use darling::FromMeta;
use proc_macro2::TokenStream;
use quote::{quote, ToTokens};
use syn::Meta;
use syn::{punctuated::Punctuated, Expr, Meta, Token};

use crate::utils::{meta_to_meta_list, meta_to_meta_name_value, nested_meta_to_meta};
use crate::utils::{meta_to_meta_list, meta_to_meta_name_value};

static SECURITY_SCHEME_ATTRIBUTE_NAME: &str = "security_scheme";
static SECURITY_SCHEME_NAME_ATTRIBUTE_NAME: &str = "name";
Expand All @@ -25,16 +25,15 @@ impl FromMeta for Security {
let meta_list = meta_to_meta_list(meta)?;
let mut this = Self::default();

for nested_meta in meta_list.nested.iter() {
let meta = nested_meta_to_meta(nested_meta)?;
for meta in meta_list.parse_args_with(Punctuated::<Meta, Token![,]>::parse_terminated)? {
let meta_ident = meta
.path()
.get_ident()
.ok_or_else(|| darling::Error::custom("Should have Ident").with_span(meta))?;
.ok_or_else(|| darling::Error::custom("Should have Ident").with_span(&meta))?;

match meta_ident {
_ if meta_ident == SECURITY_SCHEME_ATTRIBUTE_NAME => {
this.schemes.push(SecurityScheme::from_meta(meta)?)
this.schemes.push(SecurityScheme::from_meta(&meta)?)
}
_ => {
return Err(darling::Error::custom("Unsupported type of parameter")
Expand Down Expand Up @@ -67,20 +66,31 @@ impl FromMeta for SecurityScheme {
let meta_list = meta_to_meta_list(meta)?;
let mut this = Self::default();

for nested_meta in meta_list.nested.iter() {
let meta = nested_meta_to_meta(nested_meta)?;
let meta = meta_to_meta_name_value(meta)?;
for meta in meta_list.parse_args_with(Punctuated::<Meta, Token![,]>::parse_terminated)? {
let meta = meta_to_meta_name_value(&meta)?;
let meta_ident = meta
.path
.get_ident()
.ok_or_else(|| darling::Error::custom("Should have Ident").with_span(meta))?;

match meta_ident {
_ if meta_ident == SECURITY_SCHEME_NAME_ATTRIBUTE_NAME => {
this.name = String::from_value(&meta.lit)?;
let Expr::Lit(ref lit) = &meta.value else {
return Err(darling::Error::custom(
"Security scheme name should be string literal",
)
.with_span(meta_ident));
};
this.name = String::from_value(&lit.lit)?;
}
_ if meta_ident == SECURITY_SCHEME_SCOPES_ATTRIBUTE_NAME => {
let val = String::from_value(&meta.lit)?;
let Expr::Lit(ref lit) = &meta.value else {
return Err(darling::Error::custom(
"Security scheme scope should be string literal",
)
.with_span(meta_ident));
};
let val = String::from_value(&lit.lit)?;
this.scopes = val.split(',').map(|v| v.to_owned()).collect();
}
_ => {
Expand Down
34 changes: 12 additions & 22 deletions okapi-operation-macro/src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use darling::ast::NestedMeta;
use proc_macro2::TokenStream;
use quote::{quote, ToTokens};
use syn::{Attribute, AttributeArgs, Meta, MetaList, MetaNameValue, NestedMeta};
use syn::{punctuated::Punctuated, Attribute, Meta, MetaList, MetaNameValue, Token};

use crate::error::Error;

Expand All @@ -9,27 +10,23 @@ pub(super) fn quote_option<T: ToTokens>(v: &Option<T>) -> TokenStream {
.map_or(quote! { None }, |x| quote! { Some(#x.into()) })
}

pub(super) fn attribute_to_args(
attr: &Attribute,
allow_empty: bool,
) -> Result<AttributeArgs, Error> {
if let Meta::List(list) = attr.parse_meta()? {
Ok(list.nested.into_iter().collect())
} else if allow_empty {
Ok(AttributeArgs::new())
} else {
Err(Error::syn_spanned(
attr,
"Empty attribute supported only at the top of fn item attributes",
))
pub(super) fn attribute_to_args(attr: &Attribute) -> Result<Vec<NestedMeta>, Error> {
match &attr.meta {
Meta::Path(_) => Ok(Vec::new()),
Meta::List(x) => Ok(x
.parse_args_with(Punctuated::<Meta, Token![,]>::parse_terminated)?
.into_iter()
.map(NestedMeta::Meta)
.collect()),
Meta::NameValue(_) => Err(Error::syn_spanned(attr, "expected parentheses")),
}
}

pub(super) fn take_attributes(attrs: &mut Vec<Attribute>, attr_name: &str) -> Vec<Attribute> {
let mut non_matched_attrs = vec![];
let mut result = vec![];
for attr in attrs.drain(..) {
if attr.path.get_ident().map_or(false, |x| x == attr_name) {
if attr.path().get_ident().map_or(false, |x| x == attr_name) {
result.push(attr);
} else {
non_matched_attrs.push(attr);
Expand Down Expand Up @@ -66,10 +63,3 @@ pub(super) fn meta_to_meta_name_value(meta: &Meta) -> Result<&MetaNameValue, dar
.with_span(rest)),
}
}

pub(super) fn nested_meta_to_meta(nested_meta: &NestedMeta) -> Result<&Meta, darling::Error> {
match nested_meta {
NestedMeta::Meta(meta) => Ok(meta),
rest => Err(darling::Error::custom("should be NestedMeta::Meta").with_span(rest)),
}
}

0 comments on commit 9df21a2

Please sign in to comment.