in dev/src/generate/parser.rs [230:283]
fn parse_field(field: Field) -> Result<Config> {
let name = field
.ident
.clone()
.ok_or_else(|| anyhow!("field name is missing for {:?}", &field))?;
let deprecated = Self::parse_attr_deprecated(&field)?;
let comments = Self::parse_attr_comments(&field)?;
let (cfg_type, optional) = match &field.ty {
Type::Path(TypePath { path, .. }) => {
let segment = path
.segments
.last()
.ok_or_else(|| anyhow!("config type must be provided for {field:?}"))?;
let optional = segment.ident == "Option";
let type_name = if optional {
if let PathArguments::AngleBracketed(args) = &segment.arguments {
if let Some(GenericArgument::Type(Type::Path(inner_path))) =
args.args.first()
{
if let Some(inner_segment) = inner_path.path.segments.last() {
inner_segment.ident.to_string()
} else {
unreachable!("Option must have segment")
}
} else {
unreachable!("Option must have GenericArgument")
}
} else {
unreachable!("Option must have angle bracketed arguments")
}
} else {
segment.ident.to_string()
};
let typ = type_name.as_str().parse()?;
let optional = optional || typ == ConfigType::Bool;
(typ, optional)
}
v => return Err(anyhow!("unsupported config type {v:?}")),
};
Ok(Config {
name: name.to_string(),
value: cfg_type,
optional,
deprecated,
comments,
})
}