codd/expression/
difference.rs1use super::{view::ViewRef, Expression, IntoExpression, Visitor};
2use crate::Tuple;
3use std::marker::PhantomData;
4
5#[derive(Clone, Debug)]
25pub struct Difference<T, L, R>
26where
27 T: Tuple,
28 L: Expression<T>,
29 R: Expression<T>,
30{
31 left: L,
32 right: R,
33 relation_deps: Vec<String>,
34 view_deps: Vec<ViewRef>,
35 _marker: PhantomData<T>,
36}
37
38impl<T, L, R> Difference<T, L, R>
39where
40 T: Tuple,
41 L: Expression<T>,
42 R: Expression<T>,
43{
44 pub fn new<IL, IR>(left: IL, right: IR) -> Self
47 where
48 IL: IntoExpression<T, L>,
49 IR: IntoExpression<T, R>,
50 {
51 use super::dependency;
52
53 let left = left.into_expression();
54 let right = right.into_expression();
55
56 let mut deps = dependency::DependencyVisitor::new();
57 left.visit(&mut deps);
58 right.visit(&mut deps);
59 let (relation_deps, view_deps) = deps.into_dependencies();
60
61 Self {
62 left,
63 right,
64 relation_deps: relation_deps.into_iter().collect(),
65 view_deps: view_deps.into_iter().collect(),
66 _marker: PhantomData,
67 }
68 }
69
70 #[inline(always)]
72 pub fn left(&self) -> &L {
73 &self.left
74 }
75
76 #[inline(always)]
78 pub fn right(&self) -> &R {
79 &self.right
80 }
81
82 #[inline(always)]
84 pub(crate) fn relation_deps(&self) -> &[String] {
85 &self.relation_deps
86 }
87
88 #[inline(always)]
90 pub(crate) fn view_deps(&self) -> &[ViewRef] {
91 &self.view_deps
92 }
93}
94
95impl<T, L, R> Expression<T> for Difference<T, L, R>
96where
97 T: Tuple,
98 L: Expression<T>,
99 R: Expression<T>,
100{
101 fn visit<V>(&self, visitor: &mut V)
102 where
103 V: Visitor,
104 {
105 visitor.visit_difference(&self);
106 }
107}
108
109#[cfg(test)]
110mod tests {
111 use super::*;
112 use crate::{Database, Tuples};
113
114 #[test]
115 fn test_clone() {
116 let mut database = Database::new();
117 let r = database.add_relation::<i32>("r").unwrap();
118 let s = database.add_relation::<i32>("s").unwrap();
119 database.insert(&r, vec![1, 2, 3, 6].into()).unwrap();
120 database.insert(&s, vec![1, 4, 3, 5].into()).unwrap();
121 let u = Difference::new(&r, &s).clone();
122 assert_eq!(
123 Tuples::<i32>::from(vec![2, 6]),
124 database.evaluate(&u).unwrap()
125 );
126 }
127}