use syn::parse::ParseStream; use syn::punctuated::Punctuated; use syn::token::Eq; use syn::{Ident, LitStr, Token}; pub(crate) struct RegisterExtensionInput { pub aggregates: Vec, pub scalars: Vec, pub vtabs: Vec, pub vfs: Vec, } impl syn::parse::Parse for RegisterExtensionInput { fn parse(input: syn::parse::ParseStream) -> syn::Result { let mut aggregates = Vec::new(); let mut scalars = Vec::new(); let mut vtabs = Vec::new(); let mut vfs = Vec::new(); while !input.is_empty() { if input.peek(syn::Ident) && input.peek2(Token![:]) { let section_name: Ident = input.parse()?; input.parse::()?; let names = ["aggregates", "scalars", "vtabs", "vfs"]; if names.contains(§ion_name.to_string().as_str()) { let content; syn::braced!(content in input); let parsed_items = Punctuated::::parse_terminated(&content)? .into_iter() .collect(); match section_name.to_string().as_str() { "aggregates" => aggregates = parsed_items, "scalars" => scalars = parsed_items, "vtabs" => vtabs = parsed_items, "vfs" => vfs = parsed_items, _ => unreachable!(), }; if input.peek(Token![,]) { input.parse::()?; } } else { return Err(syn::Error::new(section_name.span(), "Unknown section")); } } else { return Err(input.error("Expected aggregates:, scalars:, or vtabs: section")); } } Ok(Self { aggregates, scalars, vtabs, vfs, }) } } pub(crate) struct ScalarInfo { pub name: String, pub alias: Option, } impl ScalarInfo { pub fn new(name: String, alias: Option) -> Self { Self { name, alias } } } impl syn::parse::Parse for ScalarInfo { fn parse(input: ParseStream) -> syn::parse::Result { let mut name = None; let mut alias = None; while !input.is_empty() { if let Ok(ident) = input.parse::() { if ident.to_string().as_str() == "name" { let _ = input.parse::(); name = Some(input.parse::()?); } else if ident.to_string().as_str() == "alias" { let _ = input.parse::(); alias = Some(input.parse::()?); } } if input.peek(Token![,]) { input.parse::()?; } } let Some(name) = name else { return Err(input.error("Expected name")); }; Ok(Self::new(name.value(), alias.map(|i| i.value()))) } }