ratio-metadata 0.2.2

Ratio's metadata model.
Documentation
//! # Transaction type module
//!
//! ## License
//!
//! This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
//! If a copy of the MPL was not distributed with this file,
//! You can obtain one at <https://mozilla.org/MPL/2.0/>.
//!
//! **Code examples both in the docstrings and rendered documentation are free to use.**

use std::collections::{BTreeMap, BTreeSet};
use std::fmt::Debug;

use uuid::Uuid;

use crate::metadata::{AnnotationValue, Field, WeightValue};

#[cfg(feature = "serde")]
fn is_default<T: Default + PartialEq>(value: &T) -> bool {
    value == &Default::default()
}

/// Transaction to apply to a MetadataStore.
#[derive(Clone, Debug, PartialEq, bon::Builder)]
#[cfg_attr(
    feature = "serde",
    derive(serde::Serialize, serde::Deserialize),
    serde(default, rename_all = "camelCase")
)]
#[builder(on(String, into))]
pub struct Transaction<N, K, L, W, WV, A, AV>
where
    N: Field,
    K: Field,
    L: Field,
    W: Field,
    WV: WeightValue,
    A: Field,
    AV: AnnotationValue,
{
    /// Transaction mode.
    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "is_default"))]
    #[builder(default)]
    pub mode: TransactionMode,

    /// Instance identifier.
    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
    #[builder(into)]
    pub id: Option<Uuid>,

    /// Name associated with this instance.
    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
    #[builder(into)]
    pub name: Option<N>,

    /// Kind of object or main category associated with this instance.
    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
    #[builder(into)]
    pub kind: Option<K>,

    /// Set of labels associated with this instance.
    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
    pub labels: Option<BTreeSet<L>>,

    /// Numerical weights associated with this instance.
    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
    pub weights: Option<BTreeMap<W, WV>>,

    /// Free-form annotations associated with this instance.
    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
    pub annotations: Option<BTreeMap<A, AV>>,
}
impl<N, K, L, W, WV, A, AV> Default for Transaction<N, K, L, W, WV, A, AV>
where
    N: Field,
    K: Field,
    L: Field,
    W: Field,
    WV: WeightValue,
    A: Field,
    AV: AnnotationValue,
{
    fn default() -> Self {
        Self {
            mode: Default::default(),
            id: Default::default(),
            name: Default::default(),
            kind: Default::default(),
            labels: Default::default(),
            weights: Default::default(),
            annotations: Default::default(),
        }
    }
}

impl<N, K, L, W, WV, A, AV> Transaction<N, K, L, W, WV, A, AV>
where
    N: Field,
    K: Field,
    L: Field,
    W: Field,
    WV: WeightValue,
    A: Field,
    AV: AnnotationValue,
{
    /// Strip the ID from the transaction.
    pub fn strip_id(&mut self) -> Option<Uuid> {
        self.id.take()
    }
}
/// Metadata transaction mode.
/// Whether to replace any existing value, or append to it where possible.
/// This mainly changes the behavior for sets and maps.
#[derive(Copy, Clone, Debug, Default, PartialEq)]
#[cfg_attr(
    feature = "serde",
    derive(serde::Serialize, serde::Deserialize),
    serde(rename_all = "camelCase")
)]
pub enum TransactionMode {
    Replace,
    #[default]
    Append,
}