fn unify()

in serde-reflection/src/format.rs [602:680]


    fn unify(&mut self, format: Format) -> Result<()> {
        match (self, format) {
            (format1, Self::Variable(variable2)) => {
                if let Some(format2) = variable2.borrow_mut().deref_mut() {
                    format1.unify(std::mem::take(format2))?;
                }
                *variable2.borrow_mut() = Some(format1.clone());
            }
            (Self::Variable(variable1), format2) => {
                let inner_variable = match variable1.borrow_mut().deref_mut() {
                    value1 @ None => {
                        *value1 = Some(format2);
                        None
                    }
                    Some(format1) => {
                        format1.unify(format2)?;
                        match format1 {
                            Self::Variable(variable) => Some(variable.clone()),
                            _ => None,
                        }
                    }
                };
                // Reduce multiple indirections to a single one.
                if let Some(variable) = inner_variable {
                    *variable1 = variable;
                }
            }

            (Self::Unit, Self::Unit)
            | (Self::Bool, Self::Bool)
            | (Self::I8, Self::I8)
            | (Self::I16, Self::I16)
            | (Self::I32, Self::I32)
            | (Self::I64, Self::I64)
            | (Self::I128, Self::I128)
            | (Self::U8, Self::U8)
            | (Self::U16, Self::U16)
            | (Self::U32, Self::U32)
            | (Self::U64, Self::U64)
            | (Self::U128, Self::U128)
            | (Self::F32, Self::F32)
            | (Self::F64, Self::F64)
            | (Self::Char, Self::Char)
            | (Self::Str, Self::Str)
            | (Self::Bytes, Self::Bytes) => (),

            (Self::TypeName(name1), Self::TypeName(name2)) if *name1 == name2 => (),

            (Self::Option(format1), Self::Option(format2))
            | (Self::Seq(format1), Self::Seq(format2)) => {
                format1.as_mut().unify(*format2)?;
            }

            (Self::Tuple(formats1), Self::Tuple(formats2)) if formats1.len() == formats2.len() => {
                for (format1, format2) in formats1.iter_mut().zip(formats2.into_iter()) {
                    format1.unify(format2)?;
                }
            }

            (
                Self::Map {
                    key: key1,
                    value: value1,
                },
                Self::Map {
                    key: key2,
                    value: value2,
                },
            ) => {
                key1.as_mut().unify(*key2)?;
                value1.as_mut().unify(*value2)?;
            }

            (format1, format2) => {
                return Err(unification_error(format1, format2));
            }
        }
        Ok(())
    }