rsdiff_core/ops/kinds/
nary.rs

1/*
2   Appellation: nary <mod>
3   Contrib: FL03 <jo3mccain@icloud.com>
4*/
5use crate::ops::{Evaluate, Nary, OpKind, Operand, Params};
6use strum::{AsRefStr, Display, EnumCount, EnumIs, EnumIter, VariantNames};
7
8#[derive(
9    AsRefStr,
10    Clone,
11    Copy,
12    Debug,
13    Display,
14    EnumCount,
15    EnumIs,
16    EnumIter,
17    Eq,
18    Hash,
19    Ord,
20    PartialEq,
21    PartialOrd,
22    VariantNames,
23)]
24#[cfg_attr(
25    feature = "serde",
26    derive(serde::Deserialize, serde::Serialize),
27    serde(rename_all = "lowercase", untagged)
28)]
29#[strum(serialize_all = "lowercase")]
30pub enum NaryOp {
31    Product(Product),
32    Sum(Sum),
33}
34
35impl NaryOp {
36    pub fn sum() -> Self {
37        Self::Sum(Sum::new())
38    }
39
40    pub fn name(&self) -> &str {
41        self.as_ref()
42    }
43
44    pub fn kind(&self) -> OpKind {
45        OpKind::Nary
46    }
47}
48
49impl Operand for NaryOp {
50    type Kind = Nary;
51
52    fn name(&self) -> &str {
53        self.as_ref()
54    }
55
56    fn optype(&self) -> Self::Kind {
57        Nary
58    }
59}
60
61operation!(Product<Nary>.product, Sum<Nary>.sum);
62
63impl<P, T> Evaluate<P> for Product
64where
65    T: Clone + core::iter::Product,
66    P: Params<Pattern = Vec<T>>,
67{
68    type Output = T;
69
70    fn eval(&self, params: P) -> T {
71        params.into_pattern().iter().cloned().product()
72    }
73}