use crate::extruct_from::Ast;
use syn::{Fields, FieldsNamed, Ident, ItemStruct};
pub(crate) struct Model {
pub substruct: ItemStruct,
pub superstruct_name: Ident,
pub fields: Vec<Ident>,
}
pub(crate) fn analyze(ast: Ast) -> Model {
let substruct = ast.item;
let superstruct_name = ast
.attr
.require_ident()
.expect("validated during the parsing stage")
.to_owned();
let fields = match substruct.fields {
Fields::Named(FieldsNamed { ref named, .. }) => named
.iter()
.filter_map(|f| f.ident.clone())
.collect::<Vec<_>>(),
_ => unreachable!("validated during the parsing stage"),
};
Model {
substruct,
superstruct_name,
fields,
}
}
#[cfg(test)]
mod tests {
use syn::parse_quote;
use crate::extruct_from;
use super::*;
#[test]
fn builds_model_from_nonempty_named_struct() {
let ast = extruct_from::Ast {
attr: parse_quote!(SuperStruct),
item: parse_quote!(
struct NamedStruct {
first: u64,
second: String,
third: Vec<char>,
}
),
};
let model = analyze(ast);
let fields: Vec<_> = ["first", "second", "third"]
.iter()
.map(|s| s.to_owned())
.collect();
assert_eq!("SuperStruct", model.superstruct_name.to_string());
assert_eq!("NamedStruct", model.substruct.ident.to_string());
assert_eq!(
fields,
model
.fields
.iter()
.map(|ident| ident.to_string())
.collect::<Vec<_>>()
);
}
#[test]
fn builds_model_from_empty_named_struct() {
let ast = extruct_from::Ast {
attr: parse_quote!(SuperStruct),
item: parse_quote!(
struct NamedStruct {}
),
};
let model = analyze(ast);
assert_eq!("SuperStruct", model.superstruct_name.to_string());
assert_eq!("NamedStruct", model.substruct.ident.to_string());
assert!(model.fields.is_empty());
}
}