openconfiguration 1.7.0

OpenConfiguration (OC) is a modular, efficient and flexible approach for the uni-directional exchange of visual e-commerce configurations.
Documentation
use std::collections::HashMap;

use indexmap::IndexMap;

use super::Visitor;

pub use openconfiguration_derive::Visitable;

pub(crate) trait Visitable {
    fn visit_with(&mut self, visitor: &mut dyn Visitor);
}

#[macro_export]
macro_rules! impl_visitable_noop {
    ($name:ident) => {
        impl crate::support::Visitable for $name {
            fn visit_with(&mut self, _visitor: &mut dyn crate::support::Visitor) {}
        }
    };
    ($modname:ident :: $name:ident) => {
        impl crate::support::Visitable for $modname::$name {
            fn visit_with(&mut self, _visitor: &mut dyn crate::support::Visitor) {}
        }
    };
}

impl_visitable_noop!(f64);
impl_visitable_noop!(serde_json::Value);
impl_visitable_noop!(String);

impl<T: Visitable> Visitable for Option<T> {
    fn visit_with(&mut self, visitor: &mut dyn Visitor) {
        if let Some(value) = self {
            value.visit_with(visitor);
        }
    }
}

impl<T: Visitable> Visitable for Vec<T> {
    fn visit_with(&mut self, visitor: &mut dyn Visitor) {
        for value in self {
            value.visit_with(visitor);
        }
    }
}

impl<K, V: Visitable> Visitable for HashMap<K, V> {
    fn visit_with(&mut self, visitor: &mut dyn Visitor) {
        for value in self.values_mut() {
            value.visit_with(visitor);
        }
    }
}

impl<K, V: Visitable> Visitable for IndexMap<K, V> {
    fn visit_with(&mut self, visitor: &mut dyn Visitor) {
        for value in self.values_mut() {
            value.visit_with(visitor);
        }
    }
}

pub(crate) trait MaybePath {
    fn visit_as_path(&mut self, visitor: &mut dyn Visitor);
}

impl MaybePath for Option<String> {
    fn visit_as_path(&mut self, visitor: &mut dyn Visitor) {
        if let Some(value) = self {
            visitor.visit_path(value);
        }
    }
}

impl MaybePath for String {
    fn visit_as_path(&mut self, visitor: &mut dyn Visitor) {
        visitor.visit_path(self);
    }
}

pub(crate) fn visit_path<T: MaybePath>(value: &mut T, visitor: &mut dyn Visitor) {
    value.visit_as_path(visitor);
}