crate::ix!();
pub struct FromImplGenerationConfigEmitter {
stack: Vec<ErrorEnum>,
storage: Vec<FromImplGenerationConfig>,
map: HashMap<Ident,ErrorEnum>,
}
impl FromImplGenerationConfigEmitter {
pub fn new(tree: &ErrorTree) -> Self {
let mut map = HashMap::new();
for e in tree.enums.iter() {
map.insert(
e.ident.clone(),
e.clone()
);
}
Self {
stack: Vec::new(),
storage: Vec::new(),
map,
}
}
pub fn emit(self) -> Vec<FromImplGenerationConfig> {
self.storage
}
fn generate_from_impls(&mut self, variant: &ErrorVariant)
-> Result<(), ConversionChainError>
{
match variant {
ErrorVariant::Wrapped(ident,ty) => {
self.storage.push(
FromImplGenerationConfig::from(
ConversionChain::new_from_treewalker(&self.stack,ident,ty)?
)
);
let ty_ident = ty.as_ident().expect("expected type to be convertable to ident");
if let Some(ref error_enum) = self.map.get(&ty_ident).cloned() {
if !self.stack.iter().any(|e| e.ident == error_enum.ident) {
self.visit_error_enum(error_enum);
}
}
},
_ => {}
}
Ok(())
}
#[allow(dead_code)]
fn print_stack_path(&self) {
let path: Vec<_> = self.stack.iter().map(|e| e.ident.to_string()).collect();
println!("Current Path: {:?}", path);
}
}
impl ErrorTreeVisitor for FromImplGenerationConfigEmitter {
fn visit_error_enum(&mut self, e: &ErrorEnum) {
self.stack.push(e.clone());
for variant in &e.variants {
self.generate_from_impls(variant).expect("ConversionChain creation failed");
}
self.stack.pop(); }
}