rotz 1.2.1

Fully cross platform dotfile manager written in rust.
use std::str::FromStr;

#[cfg(test)]
use fake::Dummy;
use indexmap::IndexMap;
use tap::TryConv;
#[cfg(feature = "profiling")]
use tracing::instrument;

#[cfg(test)]
use super::IndexMapFaker;
use crate::{FileFormat, helpers};

use super::{CapabilitiesCanonical, DotComplex, Selectors};

#[derive(Debug, Default, Clone)]
#[cfg_attr(test, derive(Dummy))]
pub struct DotCanonical {
  #[cfg_attr(test, dummy(faker = "IndexMapFaker"))]
  pub selectors: IndexMap<Selectors, CapabilitiesCanonical>,
}

impl TryFrom<DotComplex> for DotCanonical {
  type Error = Vec<helpers::ParseError>;
  #[cfg_attr(feature = "profiling", instrument)]
  fn try_from(value: DotComplex) -> Result<Self, Self::Error> {
    let mut errors = Self::Error::new();
    let mut selectors = IndexMap::new();
    for (selector, dot) in value.selectors {
      match Selectors::from_str(&selector) {
        Ok(f) => {
          selectors.insert(f, dot.into());
        }
        Err(e) => {
          errors.push(helpers::ParseError::Selector(e));
        }
      }
    }
    if !errors.is_empty() {
      return Err(errors);
    }
    Ok(Self { selectors })
  }
}

impl DotCanonical {
  #[cfg_attr(feature = "profiling", instrument)]
  pub(crate) fn parse(value: &str, format: FileFormat) -> Result<Self, Vec<helpers::ParseError>> {
    DotComplex::parse(value, format)?.try_conv::<DotCanonical>()
  }
}