in serde-reflection/src/format.rs [128:175]
fn visit<'a>(&'a self, f: &mut dyn FnMut(&'a Format) -> Result<()>) -> Result<()>;
/// Mutably visit all the formats in `self` in a depth-first way.
/// * Replace variables (if any) with their known values then apply the
/// visiting function `f`.
/// * Return an error if any variable has still an unknown value (thus cannot be removed).
fn visit_mut(&mut self, f: &mut dyn FnMut(&mut Format) -> Result<()>) -> Result<()>;
/// Update variables and add missing enum variants so that the terms match.
/// This is a special case of [term unification](https://en.wikipedia.org/wiki/Unification_(computer_science)):
/// * Variables occurring in `other` must be "fresh" and distinct
/// from each other. By "fresh", we mean that they do not occur in `self`
/// and have no known value yet.
/// * If needed, enums in `self` will be extended with new variants taken from `other`.
/// * Although the parameter `other` is consumed (i.e. taken by value), all
/// variables occurring either in `self` or `other` are correctly updated.
fn unify(&mut self, other: Self) -> Result<()>;
/// Finalize the formats within `self` by removing variables and making sure
/// that all eligible tuples are compressed into a `TupleArray`. Return an error
/// if any variable has an unknown value.
fn normalize(&mut self) -> Result<()> {
self.visit_mut(&mut |format: &mut Format| {
let normalized = match format {
Format::Tuple(formats) => {
let size = formats.len();
if size <= 1 {
return Ok(());
}
let format0 = &formats[0];
for format in formats.iter().skip(1) {
if format != format0 {
return Ok(());
}
}
Format::TupleArray {
content: Box::new(std::mem::take(&mut formats[0])),
size,
}
}
_ => {
return Ok(());
}
};
*format = normalized;
Ok(())
})
}