substrait_validator/input/
traits.rs1use crate::output::primitive_data;
7use crate::output::tree;
8use crate::parse::context;
9
10pub trait InputNode {
12 fn type_to_node() -> tree::Node;
16
17 fn data_to_node(&self) -> tree::Node;
19
20 fn oneof_variant(&self) -> Option<&'static str>;
23
24 fn parse_unknown(&self, context: &mut context::Context<'_>) -> bool;
28}
29
30pub trait ProtoMessage: InputNode {
33 fn proto_message_type() -> &'static str;
35}
36
37pub trait ProtoOneOf: InputNode {
42 fn proto_oneof_variant(&self) -> &'static str;
44}
45
46pub trait ProtoPrimitive: InputNode {
48 fn proto_primitive_type() -> &'static str;
50
51 fn proto_primitive_default() -> primitive_data::PrimitiveData;
54
55 fn proto_primitive_data(&self) -> primitive_data::PrimitiveData;
58
59 fn proto_primitive_is_default(&self) -> bool;
61}
62
63pub trait ProtoEnum: ProtoPrimitive {
67 fn proto_enum_type() -> &'static str;
69
70 fn proto_enum_default_variant() -> &'static str;
72
73 fn proto_enum_variant(&self) -> &'static str;
75
76 fn proto_enum_from_i32(x: i32) -> Option<Self>
79 where
80 Self: Sized;
81}
82
83impl<T: ProtoEnum> ProtoPrimitive for T {
86 fn proto_primitive_type() -> &'static str {
87 T::proto_enum_type()
88 }
89
90 fn proto_primitive_default() -> primitive_data::PrimitiveData {
91 primitive_data::PrimitiveData::Enum(T::proto_enum_default_variant())
92 }
93
94 fn proto_primitive_data(&self) -> primitive_data::PrimitiveData {
95 primitive_data::PrimitiveData::Enum(self.proto_enum_variant())
96 }
97
98 fn proto_primitive_is_default(&self) -> bool {
99 self.proto_enum_variant() == T::proto_enum_default_variant()
100 }
101}
102
103impl<T: ProtoPrimitive> InputNode for T {
111 fn type_to_node() -> tree::Node {
112 tree::NodeType::ProtoPrimitive(T::proto_primitive_type(), T::proto_primitive_default())
113 .into()
114 }
115
116 fn data_to_node(&self) -> tree::Node {
117 tree::NodeType::ProtoPrimitive(T::proto_primitive_type(), self.proto_primitive_data())
118 .into()
119 }
120
121 fn oneof_variant(&self) -> Option<&'static str> {
122 None
123 }
124
125 fn parse_unknown(&self, _context: &mut context::Context<'_>) -> bool {
126 false
127 }
128}
129
130impl InputNode for () {
131 fn type_to_node() -> tree::Node {
132 tree::NodeType::ProtoMessage("google.protobuf.Empty").into()
133 }
134
135 fn data_to_node(&self) -> tree::Node {
136 tree::NodeType::ProtoMessage("google.protobuf.Empty").into()
137 }
138
139 fn oneof_variant(&self) -> Option<&'static str> {
140 None
141 }
142
143 fn parse_unknown(&self, _context: &mut context::Context<'_>) -> bool {
144 false
145 }
146}
147
148impl ProtoMessage for () {
149 fn proto_message_type() -> &'static str {
150 "google.protobuf.Empty"
151 }
152}
153
154#[cfg(test)]
155mod tests {
156 use super::*;
157 use crate::input::proto::substrait;
158 use crate::output::primitive_data;
159 use crate::output::tree;
160
161 #[test]
162 fn message() {
163 assert_eq!(substrait::Plan::proto_message_type(), "substrait.Plan");
164 assert_eq!(
165 substrait::Plan::type_to_node(),
166 tree::Node {
167 class: tree::Class::Misc,
168 brief: None,
169 summary: None,
170 node_type: tree::NodeType::ProtoMessage("substrait.Plan"),
171 data_type: None,
172 data: vec![],
173 }
174 );
175
176 let msg = substrait::Plan::default();
177 assert_eq!(
178 msg.data_to_node(),
179 tree::Node {
180 class: tree::Class::Misc,
181 brief: None,
182 summary: None,
183 node_type: tree::NodeType::ProtoMessage("substrait.Plan"),
184 data_type: None,
185 data: vec![],
186 }
187 );
188 assert_eq!(msg.oneof_variant(), None);
189 }
190
191 #[test]
192 fn oneof() {
193 assert_eq!(
194 substrait::plan_rel::RelType::type_to_node(),
195 tree::Node {
196 class: tree::Class::Misc,
197 brief: None,
198 summary: None,
199 node_type: tree::NodeType::ProtoMissingOneOf,
200 data_type: None,
201 data: vec![],
202 }
203 );
204
205 let oneof = substrait::plan_rel::RelType::Rel(substrait::Rel::default());
206 assert_eq!(oneof.proto_oneof_variant(), "rel");
207 assert_eq!(
208 oneof.data_to_node(),
209 tree::Node {
210 class: tree::Class::Misc,
211 brief: None,
212 summary: None,
213 node_type: tree::NodeType::ProtoMessage("substrait.Rel"),
214 data_type: None,
215 data: vec![],
216 }
217 );
218 assert_eq!(oneof.oneof_variant(), Some("rel"));
219 }
220
221 #[test]
222 fn enumeration() {
223 assert_eq!(
224 substrait::AggregationPhase::proto_enum_type(),
225 "substrait.AggregationPhase"
226 );
227 assert_eq!(
228 substrait::AggregationPhase::proto_enum_default_variant(),
229 "AGGREGATION_PHASE_UNSPECIFIED"
230 );
231 assert_eq!(
232 substrait::AggregationPhase::Unspecified.proto_enum_variant(),
233 "AGGREGATION_PHASE_UNSPECIFIED"
234 );
235
236 assert_eq!(
237 substrait::AggregationPhase::proto_primitive_type(),
238 "substrait.AggregationPhase"
239 );
240 assert_eq!(
241 substrait::AggregationPhase::proto_primitive_default(),
242 primitive_data::PrimitiveData::Enum("AGGREGATION_PHASE_UNSPECIFIED")
243 );
244 assert_eq!(
245 substrait::AggregationPhase::Unspecified.proto_primitive_data(),
246 primitive_data::PrimitiveData::Enum("AGGREGATION_PHASE_UNSPECIFIED")
247 );
248
249 assert_eq!(
250 substrait::AggregationPhase::type_to_node(),
251 tree::Node {
252 class: tree::Class::Misc,
253 brief: None,
254 summary: None,
255 node_type: tree::NodeType::ProtoPrimitive(
256 "substrait.AggregationPhase",
257 primitive_data::PrimitiveData::Enum("AGGREGATION_PHASE_UNSPECIFIED")
258 ),
259 data_type: None,
260 data: vec![],
261 }
262 );
263 assert_eq!(
264 substrait::AggregationPhase::Unspecified.data_to_node(),
265 tree::Node {
266 class: tree::Class::Misc,
267 brief: None,
268 summary: None,
269 node_type: tree::NodeType::ProtoPrimitive(
270 "substrait.AggregationPhase",
271 primitive_data::PrimitiveData::Enum("AGGREGATION_PHASE_UNSPECIFIED")
272 ),
273 data_type: None,
274 data: vec![],
275 }
276 );
277 assert_eq!(
278 substrait::AggregationPhase::Unspecified.oneof_variant(),
279 None
280 );
281 }
282
283 #[test]
284 fn primitive() {
285 assert_eq!(u32::proto_primitive_type(), "uint32");
286 assert_eq!(
287 u32::proto_primitive_default(),
288 primitive_data::PrimitiveData::Unsigned(0)
289 );
290 assert_eq!(
291 42u32.proto_primitive_data(),
292 primitive_data::PrimitiveData::Unsigned(42)
293 );
294
295 assert_eq!(
296 u32::type_to_node(),
297 tree::Node {
298 class: tree::Class::Misc,
299 brief: None,
300 summary: None,
301 node_type: tree::NodeType::ProtoPrimitive(
302 "uint32",
303 primitive_data::PrimitiveData::Unsigned(0)
304 ),
305 data_type: None,
306 data: vec![],
307 }
308 );
309 assert_eq!(
310 42u32.data_to_node(),
311 tree::Node {
312 class: tree::Class::Misc,
313 brief: None,
314 summary: None,
315 node_type: tree::NodeType::ProtoPrimitive(
316 "uint32",
317 primitive_data::PrimitiveData::Unsigned(42)
318 ),
319 data_type: None,
320 data: vec![],
321 }
322 );
323 assert_eq!(42u32.oneof_variant(), None);
324 }
325}