Skip to main content

harmos_domain/inventory/
operations.rs

1/* ***
2 *
3 * Harmos
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * ***
8 */
9
10/* === Modules === */
11
12/* === Re-Exports === */
13
14/* === Imports === */
15
16// Standard Library Imports
17use std::collections::{BTreeMap, BTreeSet};
18// Third Party Imports
19
20// Local Imports
21use crate::operations::Definition;
22
23/* === Constants === */
24
25/* === Macros === */
26
27/* === Type Aliases === */
28
29/* === Structs === */
30
31/* === Enums === */
32
33#[derive(Debug, thiserror::Error)]
34pub enum Error {
35    #[error("the operation definitions differ from the admitted catalog")]
36    Mismatch,
37
38    #[error("operation inventory is invalid: {source}")]
39    Invalid {
40        #[source]
41        source: crate::Error,
42    },
43}
44
45/* === Traits === */
46
47/* === Implementations === */
48
49/* === Public Functions === */
50
51pub fn validate(operations: &[Definition]) -> Result<(), Error> {
52    let mut ids = BTreeSet::new();
53    for operation in operations {
54        operation.validate().map_err(|source| Error::Invalid { source })?;
55        if !ids.insert(&operation.id) {
56            return Err(Error::Invalid { source: crate::Error::DuplicateOperation { id: operation.id.as_str().to_owned() } });
57        }
58    }
59    Ok(())
60}
61
62pub fn validate_match(expected: &[Definition], actual: &[Definition]) -> Result<(), Error> {
63    validate(expected)?;
64    validate(actual)?;
65    let expected: BTreeMap<_, _> = expected.iter().map(|entry| (&entry.id, entry)).collect();
66    if expected.len() != actual.len() || actual.iter().any(|entry| expected.get(&entry.id).is_none_or(|declared| *declared != entry)) {
67        return Err(Error::Mismatch);
68    }
69    Ok(())
70}
71
72/* === Private Functions === */
73
74/* === Tests === */