triblespace_core/query/
patchconstraint.rs1use crate::id::id_from_value;
2use crate::id::id_into_value;
3use crate::id::ID_LEN;
4use crate::patch::IdentitySchema;
5use crate::patch::PATCH;
6use crate::value::RawValue;
7use crate::value::ValueSchema;
8use crate::value::VALUE_LEN;
9
10use super::Binding;
11use super::Constraint;
12use super::ContainsConstraint;
13use super::Variable;
14use super::VariableId;
15use super::VariableSet;
16
17pub struct PatchValueConstraint<'a, T: ValueSchema> {
21 variable: Variable<T>,
22 patch: &'a PATCH<VALUE_LEN, IdentitySchema, ()>,
23}
24
25impl<'a, T: ValueSchema> PatchValueConstraint<'a, T> {
26 pub fn new(variable: Variable<T>, patch: &'a PATCH<VALUE_LEN, IdentitySchema, ()>) -> Self {
28 PatchValueConstraint { variable, patch }
29 }
30}
31
32impl<'a, S: ValueSchema> Constraint<'a> for PatchValueConstraint<'a, S> {
33 fn variables(&self) -> VariableSet {
34 VariableSet::new_singleton(self.variable.index)
35 }
36
37 fn estimate(&self, variable: VariableId, _binding: &Binding) -> Option<usize> {
38 if self.variable.index == variable {
39 Some(self.patch.len() as usize)
40 } else {
41 None
42 }
43 }
44
45 fn propose(&self, variable: VariableId, _binding: &Binding, proposals: &mut Vec<RawValue>) {
46 if self.variable.index == variable {
47 self.patch
48 .infixes(&[0; 0], &mut |&k: &[u8; 32]| proposals.push(k));
49 }
50 }
51
52 fn confirm(&self, variable: VariableId, _binding: &Binding, proposals: &mut Vec<RawValue>) {
53 if self.variable.index == variable {
54 proposals.retain(|v| self.patch.has_prefix(v));
55 }
56 }
57}
58
59impl<'a, S: ValueSchema> ContainsConstraint<'a, S> for &'a PATCH<VALUE_LEN, IdentitySchema, ()> {
60 type Constraint = PatchValueConstraint<'a, S>;
61
62 fn has(self, v: Variable<S>) -> Self::Constraint {
63 PatchValueConstraint::new(v, self)
64 }
65}
66
67pub struct PatchIdConstraint<S>
73where
74 S: ValueSchema,
75{
76 variable: Variable<S>,
77 patch: PATCH<ID_LEN, IdentitySchema, ()>,
78}
79
80impl<S> PatchIdConstraint<S>
81where
82 S: ValueSchema,
83{
84 pub fn new(variable: Variable<S>, patch: PATCH<ID_LEN, IdentitySchema, ()>) -> Self {
86 PatchIdConstraint { variable, patch }
87 }
88}
89
90impl<'a, S> Constraint<'a> for PatchIdConstraint<S>
91where
92 S: ValueSchema,
93{
94 fn variables(&self) -> VariableSet {
95 VariableSet::new_singleton(self.variable.index)
96 }
97
98 fn estimate(&self, variable: VariableId, _binding: &Binding) -> Option<usize> {
99 if self.variable.index == variable {
100 Some(self.patch.len() as usize)
101 } else {
102 None
103 }
104 }
105
106 fn propose(&self, variable: VariableId, _binding: &Binding, proposals: &mut Vec<RawValue>) {
107 if self.variable.index == variable {
108 self.patch.infixes(&[0; 0], &mut |id: &[u8; 16]| {
109 proposals.push(id_into_value(id))
110 });
111 }
112 }
113
114 fn confirm(&self, _variable: VariableId, _binding: &Binding, proposals: &mut Vec<RawValue>) {
115 proposals.retain(|v| {
116 if let Some(id) = id_from_value(v) {
117 self.patch.has_prefix(&id)
118 } else {
119 false
120 }
121 });
122 }
123}
124
125impl<'a, S: ValueSchema> ContainsConstraint<'a, S> for PATCH<ID_LEN, IdentitySchema, ()> {
126 type Constraint = PatchIdConstraint<S>;
127
128 fn has(self, v: Variable<S>) -> Self::Constraint {
129 PatchIdConstraint::new(v, self)
130 }
131}