mirror of
https://github.com/girlbossceo/conduwuit.git
synced 2024-12-04 20:08:10 +00:00
initial example-config generator
Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
parent
370db5ccea
commit
ba253738dc
|
@ -5,6 +5,7 @@ use std::{
|
|||
path::PathBuf,
|
||||
};
|
||||
|
||||
use conduit_macros::config_example_generator;
|
||||
use either::{
|
||||
Either,
|
||||
Either::{Left, Right},
|
||||
|
@ -27,6 +28,7 @@ pub mod check;
|
|||
pub mod proxy;
|
||||
|
||||
/// all the config options for conduwuit
|
||||
#[config_example_generator]
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[allow(clippy::struct_excessive_bools)]
|
||||
pub struct Config {
|
||||
|
|
98
src/macros/config.rs
Normal file
98
src/macros/config.rs
Normal file
|
@ -0,0 +1,98 @@
|
|||
use std::fmt::Write;
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
use quote::ToTokens;
|
||||
use syn::{Expr, ExprLit, Field, Fields, FieldsNamed, ItemStruct, Lit, Meta, MetaNameValue, Type, TypePath};
|
||||
|
||||
use crate::{utils::is_cargo_build, Result};
|
||||
|
||||
#[allow(clippy::needless_pass_by_value)]
|
||||
pub(super) fn example_generator(input: ItemStruct, args: &[Meta]) -> Result<TokenStream> {
|
||||
if is_cargo_build() {
|
||||
generate_example(&input, args)?;
|
||||
}
|
||||
|
||||
Ok(input.to_token_stream().into())
|
||||
}
|
||||
|
||||
#[allow(clippy::needless_pass_by_value)]
|
||||
#[allow(unused_variables)]
|
||||
fn generate_example(input: &ItemStruct, _args: &[Meta]) -> Result<()> {
|
||||
if let Fields::Named(FieldsNamed {
|
||||
named,
|
||||
..
|
||||
}) = &input.fields
|
||||
{
|
||||
for field in named {
|
||||
let Some(ident) = &field.ident else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let Some(doc) = get_doc_comment(field) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let Some(type_name) = get_type_name(field) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
//println!("{:?} {type_name:?}\n{doc}", ident.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_doc_comment(field: &Field) -> Option<String> {
|
||||
let mut out = String::new();
|
||||
for attr in &field.attrs {
|
||||
let Meta::NameValue(MetaNameValue {
|
||||
path,
|
||||
value,
|
||||
..
|
||||
}) = &attr.meta
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
|
||||
if !path
|
||||
.segments
|
||||
.iter()
|
||||
.next()
|
||||
.is_some_and(|s| s.ident == "doc")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
let Expr::Lit(ExprLit {
|
||||
lit,
|
||||
..
|
||||
}) = &value
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let Lit::Str(token) = &lit else {
|
||||
continue;
|
||||
};
|
||||
|
||||
writeln!(&mut out, "# {}", token.value()).expect("wrote to output string buffer");
|
||||
}
|
||||
|
||||
(!out.is_empty()).then_some(out)
|
||||
}
|
||||
|
||||
fn get_type_name(field: &Field) -> Option<String> {
|
||||
let Type::Path(TypePath {
|
||||
path,
|
||||
..
|
||||
}) = &field.ty
|
||||
else {
|
||||
return None;
|
||||
};
|
||||
|
||||
path.segments
|
||||
.iter()
|
||||
.next()
|
||||
.map(|segment| segment.ident.to_string())
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
mod admin;
|
||||
mod cargo;
|
||||
mod config;
|
||||
mod debug;
|
||||
mod implement;
|
||||
mod refutable;
|
||||
|
@ -9,7 +10,7 @@ mod utils;
|
|||
use proc_macro::TokenStream;
|
||||
use syn::{
|
||||
parse::{Parse, Parser},
|
||||
parse_macro_input, Error, Item, ItemConst, ItemEnum, ItemFn, Meta,
|
||||
parse_macro_input, Error, Item, ItemConst, ItemEnum, ItemFn, ItemStruct, Meta,
|
||||
};
|
||||
|
||||
pub(crate) type Result<T> = std::result::Result<T, Error>;
|
||||
|
@ -47,6 +48,11 @@ pub fn implement(args: TokenStream, input: TokenStream) -> TokenStream {
|
|||
attribute_macro::<ItemFn, _>(args, input, implement::implement)
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn config_example_generator(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
attribute_macro::<ItemStruct, _>(args, input, config::example_generator)
|
||||
}
|
||||
|
||||
fn attribute_macro<I, F>(args: TokenStream, input: TokenStream, func: F) -> TokenStream
|
||||
where
|
||||
F: Fn(I, &[Meta]) -> Result<TokenStream>,
|
||||
|
|
Loading…
Reference in a new issue