rsdiff_core/ops/traits/
operand.rs

1/*
2    Appellation: operand <traits>
3    Contrib: FL03 <jo3mccain@icloud.com>
4*/
5use crate::ops::{OpKind, Operator};
6
7pub trait OperandType {
8    fn kind(&self) -> OpKind;
9
10    private!();
11}
12
13pub trait Operand {
14    type Kind: OperandType;
15
16    fn kind(&self) -> OpKind {
17        self.optype().kind()
18    }
19
20    fn name(&self) -> &str;
21
22    fn optype(&self) -> Self::Kind;
23}
24
25/*
26 **************** implementations ****************
27*/
28impl<K, S> Operator for S
29where
30    K: OperandType,
31    S: Operand<Kind = K>,
32{
33    fn kind(&self) -> OpKind {
34        self.optype().kind()
35    }
36
37    fn name(&self) -> &str {
38        Operand::name(self)
39    }
40}
41
42impl OperandType for Box<dyn OperandType> {
43    fn kind(&self) -> OpKind {
44        self.as_ref().kind()
45    }
46
47    seal!();
48}
49
50impl<K> Operand for Box<dyn Operand<Kind = K>>
51where
52    K: OperandType,
53{
54    type Kind = K;
55
56    fn name(&self) -> &str {
57        self.as_ref().name()
58    }
59
60    fn optype(&self) -> Self::Kind {
61        self.as_ref().optype()
62    }
63}
64
65macro_rules! impl_operand_ty {
66    ($($kind:ident),* $(,)?) => {
67        $(
68            impl_operand_ty!(@impl $kind);
69        )*
70    };
71    (@impl $kind:ident) => {
72        #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
73        #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
74        #[repr(transparent)]
75        pub struct $kind;
76
77        impl OperandType for $kind {
78            fn kind(&self) -> OpKind {
79                OpKind::$kind
80            }
81
82            seal!();
83        }
84    };
85}
86
87impl_operand_ty!(Binary, Nary, Ternary, Unary,);