harmos-domain 0.1.5

Harmos domain model: identifiers, contracts, catalogs and storage identities.
Documentation
/* ***
 *
 * Harmos
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * ***
 */

/* === Modules === */

/* === Re-Exports === */

/* === Imports === */

// Standard Library Imports
use std::collections::{BTreeMap, BTreeSet};
// Third Party Imports

// Local Imports
use crate::operations::Definition;

/* === Constants === */

/* === Macros === */

/* === Type Aliases === */

/* === Structs === */

/* === Enums === */

#[derive(Debug, thiserror::Error)]
pub enum Error {
    #[error("the operation definitions differ from the admitted catalog")]
    Mismatch,

    #[error("operation inventory is invalid: {source}")]
    Invalid {
        #[source]
        source: crate::Error,
    },
}

/* === Traits === */

/* === Implementations === */

/* === Public Functions === */

pub fn validate(operations: &[Definition]) -> Result<(), Error> {
    let mut ids = BTreeSet::new();
    for operation in operations {
        operation.validate().map_err(|source| Error::Invalid { source })?;
        if !ids.insert(&operation.id) {
            return Err(Error::Invalid { source: crate::Error::DuplicateOperation { id: operation.id.as_str().to_owned() } });
        }
    }
    Ok(())
}

pub fn validate_match(expected: &[Definition], actual: &[Definition]) -> Result<(), Error> {
    validate(expected)?;
    validate(actual)?;
    let expected: BTreeMap<_, _> = expected.iter().map(|entry| (&entry.id, entry)).collect();
    if expected.len() != actual.len() || actual.iter().any(|entry| expected.get(&entry.id).is_none_or(|declared| *declared != entry)) {
        return Err(Error::Mismatch);
    }
    Ok(())
}

/* === Private Functions === */

/* === Tests === */