rsdiff_core/ops/traits/
operand.rs1use 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
25impl<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,);