use syn::parse::{Parse, ParseStream};
use syn::{Ident, Token, parenthesized};
use super::openapi::OpenApiArgs;
pub struct AxumApiArgs {
pub state_type: Ident,
pub openapi: Option<OpenApiArgs>,
}
impl AxumApiArgs {
pub fn enable_openapi(&self) -> bool { self.openapi.is_some() }
pub fn components(&self) -> &[syn::Type] {
self.openapi.as_ref().map(|o| o.components.as_slice()).unwrap_or(&[])
}
pub fn server(&self) -> Option<&str> { self.openapi.as_ref().and_then(|o| o.server.as_deref()) }
pub fn paths(&self) -> &[syn::Path] {
self.openapi.as_ref().map(|o| o.paths.as_slice()).unwrap_or(&[])
}
}
impl Parse for AxumApiArgs {
fn parse(input: ParseStream) -> syn::Result<Self> {
let state_type: Ident = input.parse()?;
let mut openapi = None;
while input.peek(Token![,]) {
input.parse::<Token![,]>()?;
if input.is_empty() {
break;
}
let ident: Ident = input.parse()?;
let ident_str = ident.to_string();
match ident_str.as_str() {
"openapi" => {
let config = if input.peek(syn::token::Paren) {
let content;
parenthesized!(content in input);
content.parse::<OpenApiArgs>()?
} else {
OpenApiArgs::empty()
};
openapi = Some(config);
}
_ => {
return Err(syn::Error::new_spanned(
&ident,
format!(
"unknown argument `{}`. Expected `openapi` or `openapi(...)`",
ident
),
));
}
}
}
Ok(AxumApiArgs { state_type, openapi })
}
}