1use crate::constraint::Constraint;
2use crate::ion_path::IonPath;
3use crate::ion_schema_element::IonSchemaElementType;
4use crate::isl::isl_constraint::IslConstraintValue;
5use crate::isl::isl_type::IslType;
6use crate::isl::IslVersion;
7use crate::result::{invalid_schema_error, IonSchemaResult, ValidationResult};
8use crate::system::{PendingTypes, TypeId, TypeStore};
9use crate::violation::{Violation, ViolationCode};
10use crate::IonSchemaElement;
11use ion_rs::Element;
12use ion_rs::Symbol;
13use std::fmt::{Display, Formatter};
14use std::sync::Arc;
15
16pub(crate) trait TypeValidator {
18 fn is_valid(
21 &self,
22 value: &IonSchemaElement,
23 type_store: &TypeStore,
24 ion_path: &mut IonPath,
25 ) -> bool;
26
27 fn validate(
30 &self,
31 value: &IonSchemaElement,
32 type_store: &TypeStore,
33 ion_path: &mut IonPath,
34 ) -> ValidationResult;
35}
36
37#[derive(Debug, Clone)]
41pub struct TypeDefinition {
42 id: TypeId,
43 type_store: Arc<TypeStore>,
44}
45
46impl TypeDefinition {
47 pub(crate) fn new(id: TypeId, type_store: Arc<TypeStore>) -> Self {
48 Self { id, type_store }
49 }
50
51 pub fn id(&self) -> TypeId {
52 self.id
53 }
54
55 pub fn validate<'a, I: Into<IonSchemaElement<'a>>>(&self, value: I) -> ValidationResult {
102 let type_def = self.type_store.get_type_by_id(self.id).unwrap();
103
104 let schema_element: IonSchemaElement = value.into();
106
107 type_def.validate(&schema_element, &self.type_store, &mut IonPath::default())
108 }
109}
110
111#[derive(Debug, Clone, PartialEq)]
113pub(crate) enum BuiltInTypeDefinition {
114 Atomic(IonSchemaElementType, Nullability),
115 Derived(TypeDefinitionImpl),
116}
117
118#[derive(Debug, Clone, PartialEq, Eq)]
120pub(crate) enum Nullability {
121 Nullable,
122 NotNullable,
123}
124
125impl BuiltInTypeDefinition {
126 pub(crate) fn parse_from_isl_type(
127 isl_version: IslVersion,
128 isl_type: &IslType,
129 type_store: &mut TypeStore,
130 pending_types: &mut PendingTypes,
131 ) -> IonSchemaResult<Self> {
132 let mut constraints = vec![];
133
134 let type_name = isl_type.name().map(|x| x.to_owned());
136
137 for isl_constraint in isl_type.constraints() {
139 let constraint = Constraint::resolve_from_isl_constraint(
141 isl_version,
142 &isl_constraint.constraint_value,
143 type_store,
144 pending_types,
145 true,
146 )?;
147 constraints.push(constraint);
148 }
149
150 let builtin_type_def = BuiltInTypeDefinition::Derived(TypeDefinitionImpl::new(
151 type_name.to_owned(),
152 constraints,
153 None,
154 ));
155 Ok(builtin_type_def)
156 }
157}
158
159impl TypeValidator for BuiltInTypeDefinition {
160 fn is_valid(
161 &self,
162 value: &IonSchemaElement,
163 type_store: &TypeStore,
164 ion_path: &mut IonPath,
165 ) -> bool {
166 let violation = self.validate(value, type_store, ion_path);
167 violation.is_ok()
168 }
169
170 fn validate(
171 &self,
172 value: &IonSchemaElement,
173 type_store: &TypeStore,
174 ion_path: &mut IonPath,
175 ) -> ValidationResult {
176 match &self {
177 BuiltInTypeDefinition::Atomic(ion_type, is_nullable) => {
178 if *is_nullable == Nullability::NotNullable && value.is_null() {
179 return Err(Violation::new(
180 "type_constraint",
181 ViolationCode::InvalidNull,
182 format!("expected type {ion_type:?} doesn't allow null"),
183 ion_path,
184 ));
185 }
186 if value.ion_schema_type() != *ion_type {
187 return Err(Violation::new(
188 "type_constraint",
189 ViolationCode::TypeMismatched,
190 format!(
191 "expected type {:?}, found {:?}",
192 ion_type,
193 value.ion_schema_type()
194 ),
195 ion_path,
196 ));
197 }
198 Ok(())
199 }
200 BuiltInTypeDefinition::Derived(other_type) => {
201 other_type.validate(value, type_store, ion_path)
202 }
203 }
204 }
205}
206
207impl Display for BuiltInTypeDefinition {
208 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
209 match &self {
210 BuiltInTypeDefinition::Atomic(ion_type, _) => write!(f, "{ion_type}"),
211 BuiltInTypeDefinition::Derived(type_def) => write!(f, "{type_def}"),
212 }
213 }
214}
215
216#[derive(Debug, Clone, PartialEq)]
218pub(crate) enum TypeDefinitionKind {
219 Named(TypeDefinitionImpl),
220 Anonymous(TypeDefinitionImpl),
221 BuiltIn(BuiltInTypeDefinition),
222}
223
224impl TypeDefinitionKind {
225 pub fn named<A: Into<String>, B: Into<Vec<Constraint>>>(
227 name: A,
228 constraints: B,
229 ) -> TypeDefinitionKind {
230 TypeDefinitionKind::Named(TypeDefinitionImpl::new(
231 Some(name.into()),
232 constraints.into(),
233 None,
234 ))
235 }
236
237 pub fn is_deferred_type_def(&self) -> bool {
239 match self {
240 TypeDefinitionKind::Named(type_def) => type_def.is_deferred_type_def,
241 _ => false,
242 }
243 }
244
245 pub fn anonymous<A: Into<Vec<Constraint>>>(constraints: A) -> TypeDefinitionKind {
247 TypeDefinitionKind::Anonymous(TypeDefinitionImpl::new(None, constraints.into(), None))
248 }
249
250 pub fn constraints(&self) -> &[Constraint] {
252 match &self {
253 TypeDefinitionKind::Named(named_type) => named_type.constraints(),
254 TypeDefinitionKind::Anonymous(anonymous_type) => anonymous_type.constraints(),
255 _ => &[],
256 }
257 }
258
259 pub fn is_valid_for_base_nullable_type(
263 &self,
264 value: &IonSchemaElement,
265 type_store: &TypeStore,
266 ion_path: &mut IonPath,
267 ) -> bool {
268 let built_in_type_name = match self {
270 TypeDefinitionKind::Named(_) | TypeDefinitionKind::Anonymous(_) => {
271 None
273 }
274 TypeDefinitionKind::BuiltIn(built_int_type) => match built_int_type {
275 BuiltInTypeDefinition::Atomic(ion_type, nullability) => {
276 Some(format!("${ion_type}"))
277 }
278 BuiltInTypeDefinition::Derived(type_def) => {
279 let type_name = type_def.name().as_ref().unwrap().to_string();
280 if !type_name.starts_with('$') {
281 Some(format!("${type_name}"))
282 } else {
283 Some(type_name)
284 }
285 }
286 },
287 }
288 .unwrap(); let type_def = type_store
292 .get_type_by_id(
293 type_store
294 .get_builtin_type_id(built_in_type_name.as_str())
295 .unwrap(),
296 )
297 .unwrap();
298
299 type_def.is_valid(value, type_store, ion_path)
300 }
301}
302
303impl Display for TypeDefinitionKind {
304 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
305 match &self {
306 TypeDefinitionKind::Named(named_type_def) => {
307 write!(f, "{named_type_def}")
308 }
309 TypeDefinitionKind::Anonymous(anonymous_type_def) => {
310 write!(f, "{anonymous_type_def}")
311 }
312 TypeDefinitionKind::BuiltIn(builtin_type_def) => {
313 write!(f, "{builtin_type_def}")
314 }
315 }
316 }
317}
318
319impl TypeValidator for TypeDefinitionKind {
320 fn is_valid(
321 &self,
322 value: &IonSchemaElement,
323 type_store: &TypeStore,
324 ion_path: &mut IonPath,
325 ) -> bool {
326 let violation = self.validate(value, type_store, ion_path);
327 violation.is_ok()
328 }
329
330 fn validate(
331 &self,
332 value: &IonSchemaElement,
333 type_store: &TypeStore,
334 ion_path: &mut IonPath,
335 ) -> ValidationResult {
336 match self {
337 TypeDefinitionKind::Named(named_type) => {
338 named_type.validate(value, type_store, ion_path)
339 }
340 TypeDefinitionKind::Anonymous(anonymous_type) => {
341 anonymous_type.validate(value, type_store, ion_path)
342 }
343 TypeDefinitionKind::BuiltIn(built_in_type) => {
344 built_in_type.validate(value, type_store, ion_path)
345 }
346 }
347 }
348}
349
350#[derive(Debug, Clone)]
352pub(crate) struct TypeDefinitionImpl {
353 name: Option<String>,
354 constraints: Vec<Constraint>,
355 is_deferred_type_def: bool,
369 isl_type_struct: Option<Element>,
371}
372
373impl TypeDefinitionImpl {
374 pub fn new(
375 name: Option<String>,
376 constraints: Vec<Constraint>,
377 isl_type_struct: Option<Element>,
378 ) -> Self {
379 Self {
380 name,
381 constraints,
382 is_deferred_type_def: false,
383 isl_type_struct,
384 }
385 }
386
387 pub fn new_deferred_type_def(name: String) -> Self {
388 Self {
389 name: Some(name),
390 constraints: vec![],
391 is_deferred_type_def: true,
392 isl_type_struct: None,
393 }
394 }
395
396 pub fn name(&self) -> &Option<String> {
397 &self.name
398 }
399
400 pub fn with_name(self, alias: String) -> Self {
401 Self {
402 name: Some(alias),
403 constraints: self.constraints,
404 is_deferred_type_def: self.is_deferred_type_def,
405 isl_type_struct: None,
406 }
407 }
408
409 pub fn is_deferred_type_def(&self) -> bool {
410 self.is_deferred_type_def
411 }
412
413 pub fn constraints(&self) -> &[Constraint] {
414 &self.constraints
415 }
416
417 pub(crate) fn parse_from_isl_type_and_update_pending_types(
422 isl_version: IslVersion,
423 isl_type: &IslType,
424 type_store: &mut TypeStore,
425 pending_types: &mut PendingTypes,
426 ) -> IonSchemaResult<TypeId> {
427 let mut constraints = vec![];
428
429 let type_name = isl_type.name();
431
432 if let Some(type_name) = type_name {
433 if let Some(type_def) = type_store.get_type_def_by_name(type_name) {
434 if isl_version == IslVersion::V2_0 && !type_def.is_deferred_type_def() {
435 return invalid_schema_error(format!(
436 "The schema document can not have two type definitions with same name: {}",
437 type_name
438 ));
439 }
440 }
441 pending_types.add_parent(type_name.to_owned(), type_store);
443 }
444
445 let type_id = pending_types.add_type(type_store, type_name.map(|x| x.to_owned()));
447
448 let mut found_type_constraint = false;
450 for isl_constraint in isl_type.constraints() {
451 if let IslConstraintValue::Type(_) = isl_constraint.constraint_value {
452 found_type_constraint = true;
453 }
454
455 let constraint = Constraint::resolve_from_isl_constraint(
456 isl_version,
457 &isl_constraint.constraint_value,
458 type_store,
459 pending_types,
460 isl_type.is_open_content_allowed(),
461 )?;
462 constraints.push(constraint);
463 }
464
465 let isl_struct = isl_type.isl_type_struct.as_ref();
466 if !found_type_constraint && isl_version == IslVersion::V1_0 {
468 let isl_type_name = match type_name.to_owned() {
470 Some(name) => name.to_owned(),
471 None => match isl_struct {
472 None => "".to_owned(),
473 Some(isl_type_struct) => format!("{isl_type_struct}"),
474 },
475 };
476
477 let isl_constraint: IslConstraintValue =
478 IslConstraintValue::from_ion_element(
480 isl_version,
481 "type",
482 &Element::symbol(Symbol::from("any")),
483 &isl_type_name,
484 &mut vec![],
485 )?;
486
487 let constraint = Constraint::resolve_from_isl_constraint(
488 isl_version,
489 &isl_constraint,
490 type_store,
491 pending_types,
492 true, )?;
494 constraints.push(constraint);
495 }
496
497 let type_def = TypeDefinitionImpl::new(
498 type_name.map(|x| x.to_owned()),
499 constraints,
500 isl_type.isl_type_struct.to_owned(),
501 );
502
503 let actual_type_id;
505
506 if type_name.is_some() {
507 actual_type_id = pending_types.update_named_type(
509 type_id,
510 type_name.as_ref().unwrap(),
511 type_def,
512 type_store,
513 );
514
515 pending_types.clear_parent();
517 } else {
518 actual_type_id = pending_types.update_anonymous_type(type_id, type_def, type_store);
520 }
521
522 Ok(actual_type_id)
523 }
524}
525
526impl PartialEq for TypeDefinitionImpl {
527 fn eq(&self, other: &Self) -> bool {
528 self.name() == other.name() && self.constraints == other.constraints()
529 }
530}
531
532impl TypeValidator for TypeDefinitionImpl {
533 fn is_valid(
534 &self,
535 value: &IonSchemaElement,
536 type_store: &TypeStore,
537 ion_path: &mut IonPath,
538 ) -> bool {
539 let violation = self.validate(value, type_store, ion_path);
540 violation.is_ok()
541 }
542
543 fn validate(
544 &self,
545 value: &IonSchemaElement,
546 type_store: &TypeStore,
547 ion_path: &mut IonPath,
548 ) -> ValidationResult {
549 let mut violations: Vec<Violation> = vec![];
550 let type_name = match self.name() {
551 None => match self.isl_type_struct.as_ref() {
552 None => "".to_owned(),
553 Some(anonymous_struct) => {
554 format!("{anonymous_struct}")
555 }
556 },
557 Some(name) => name.to_owned(),
558 };
559 for constraint in self.constraints() {
560 if let Err(violation) = constraint.validate(value, type_store, ion_path) {
561 violations.push(violation);
562 }
563 }
564 if violations.is_empty() {
565 return Ok(());
566 }
567 Err(Violation::with_violations(
568 type_name,
569 ViolationCode::TypeConstraintsUnsatisfied,
570 "value didn't satisfy type constraint(s)",
571 ion_path,
572 violations,
573 ))
574 }
575}
576
577impl Display for TypeDefinitionImpl {
578 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
579 let type_def_name = match &self.name {
580 None => match &self.isl_type_struct {
581 None => "".to_owned(),
582 Some(type_name) => format!("{type_name}"),
583 },
584 Some(type_name) => type_name.to_owned(),
585 };
586
587 write!(f, "{type_def_name}")
588 }
589}
590
591#[cfg(test)]
592mod type_definition_tests {
593 use super::*;
594 use crate::constraint::Constraint;
595 use crate::isl::isl_constraint::v_1_0::*;
596 use crate::isl::isl_type::v_1_0::*;
597 use crate::isl::isl_type::IslType;
598 use crate::isl::isl_type_reference::v_1_0::*;
599 use crate::isl::ranges::*;
600 use crate::isl::util::Ieee754InterchangeFormat;
601 use crate::isl::util::TimestampPrecision;
602 use crate::isl::*;
603 use crate::system::PendingTypes;
604
605 use rstest::*;
606 use std::collections::HashSet;
607
608 #[rstest(
610 isl_type, type_def,
611 case::type_constraint_with_anonymous_type(
612 anonymous_type([type_constraint(named_type_ref("int"))]),
616 TypeDefinitionKind::anonymous([Constraint::type_constraint(0)])
617 ),
618 case::type_constraint_with_named_type(
619 named_type("my_int", [type_constraint(named_type_ref("int"))]),
623 TypeDefinitionKind::named("my_int", [Constraint::type_constraint(0)])
624 ),
625 case::type_constraint_with_self_reference_type(
626 named_type("my_int", [type_constraint(named_type_ref("my_int"))]),
630 TypeDefinitionKind::named("my_int", [Constraint::type_constraint(35)])
631 ),
632 case::type_constraint_with_nested_self_reference_type(
633 named_type("my_int", [type_constraint(anonymous_type_ref([type_constraint(named_type_ref("my_int"))]))]),
637 TypeDefinitionKind::named("my_int", [Constraint::type_constraint(36)]) ),
639 case::type_constraint_with_nested_type(
640 named_type("my_int", [type_constraint(anonymous_type_ref([type_constraint(named_type_ref("int"))]))]),
644 TypeDefinitionKind::named("my_int", [Constraint::type_constraint(36)])
645 ),
646 case::type_constraint_with_nested_multiple_types(
647 named_type("my_int", [type_constraint(anonymous_type_ref([type_constraint(named_type_ref("int"))])), type_constraint(anonymous_type_ref([type_constraint(named_type_ref("my_int"))]))]),
651 TypeDefinitionKind::named("my_int", [Constraint::type_constraint(36), Constraint::type_constraint(37)])
652 ),
653 case::all_of_constraint(
654 anonymous_type([all_of([anonymous_type_ref([type_constraint(named_type_ref("int"))])])]),
658 TypeDefinitionKind::anonymous([Constraint::all_of([36]), Constraint::type_constraint(34)])
659 ),
660 case::any_of_constraint(
661 anonymous_type([any_of([anonymous_type_ref([type_constraint(named_type_ref("int"))]), anonymous_type_ref([type_constraint(named_type_ref("decimal"))])])]),
665 TypeDefinitionKind::anonymous([Constraint::any_of([36, 37]), Constraint::type_constraint(34)])
666 ),
667 case::one_of_constraint(
668 anonymous_type([one_of([anonymous_type_ref([type_constraint(named_type_ref("int"))]), anonymous_type_ref([type_constraint(named_type_ref("decimal"))])])]),
672 TypeDefinitionKind::anonymous([Constraint::one_of([36, 37]), Constraint::type_constraint(34)])
673 ),
674 case::not_constraint(
675 anonymous_type([not(anonymous_type_ref([type_constraint(named_type_ref("int"))]))]),
679 TypeDefinitionKind::anonymous([Constraint::not(36), Constraint::type_constraint(34)])
680 ),
681 case::ordered_elements_constraint(
682 anonymous_type([ordered_elements([variably_occurring_type_ref(named_type_ref("symbol"), UsizeRange::new_single_value(1)), variably_occurring_type_ref(anonymous_type_ref([type_constraint(named_type_ref("int"))]), UsizeRange::new_single_value(1))])]),
686 TypeDefinitionKind::anonymous([Constraint::ordered_elements([5, 36]), Constraint::type_constraint(34)])
687 ),
688 case::fields_constraint(
689 anonymous_type([fields(vec![("name".to_owned(), variably_occurring_type_ref(named_type_ref("string"), UsizeRange::zero_or_one())), ("id".to_owned(), variably_occurring_type_ref(named_type_ref("int"), UsizeRange::zero_or_one()))].into_iter())]),
693 TypeDefinitionKind::anonymous([Constraint::fields(vec![("name".to_owned(), 4), ("id".to_owned(), 0)].into_iter()), Constraint::type_constraint(34)])
694 ),
695 case::field_names_constraint(
696 isl_type::v_2_0::anonymous_type([isl_constraint::v_2_0::field_names(named_type_ref("symbol"), true)]),
700 TypeDefinitionKind::anonymous([Constraint::field_names(5, true), Constraint::type_constraint(34)])
701 ),
702 case::contains_constraint(
703 anonymous_type([contains([true.into(), 1.into(), "hello".to_owned().into()])]),
707 TypeDefinitionKind::anonymous([Constraint::contains([true.into(), 1.into(), "hello".to_owned().into()]), Constraint::type_constraint(34)])
708 ),
709 case::container_length_constraint(
710 anonymous_type([container_length(3.into())]),
714 TypeDefinitionKind::anonymous([Constraint::container_length(3.into()), Constraint::type_constraint(34)])
715 ),
716 case::byte_length_constraint(
717 anonymous_type([byte_length(3.into())]),
721 TypeDefinitionKind::anonymous([Constraint::byte_length(3.into()), Constraint::type_constraint(34)])
722 ),
723 case::codepoint_length_constraint(
724 anonymous_type([codepoint_length(3.into())]),
728 TypeDefinitionKind::anonymous([Constraint::codepoint_length(3.into()), Constraint::type_constraint(34)])
729 ),
730 case::element_constraint(
731 anonymous_type([element(named_type_ref("int"))]),
735 TypeDefinitionKind::anonymous([Constraint::element(0, false), Constraint::type_constraint(34)])
736 ),
737 case::distinct_element_constraint(
738 isl_type::v_2_0::anonymous_type([isl_constraint::v_2_0::element(named_type_ref("int"), true)]),
742 TypeDefinitionKind::anonymous([Constraint::element(0, true), Constraint::type_constraint(34)])
743 ),
744 case::annotations_constraint(
745 anonymous_type([annotations(vec!["closed"], vec![Symbol::from("red").into(), Symbol::from("blue").into(), Symbol::from("green").into()])]),
749 TypeDefinitionKind::anonymous([Constraint::annotations(vec!["closed"], vec![Symbol::from("red").into(), Symbol::from("blue").into(), Symbol::from("green").into()]), Constraint::type_constraint(34)])
750 ),
751 case::annotations_v2_0_constraint(
752 isl_type::v_2_0::anonymous_type([isl_constraint::v_2_0::annotations(isl_type_reference::v_2_0::anonymous_type_ref([isl_constraint::v_2_0::container_length(1.into())]))]),
756 TypeDefinitionKind::anonymous([Constraint::annotations_v2_0(36), Constraint::type_constraint(34)])
757 ),
758 case::precision_constraint(
759 anonymous_type([precision(3.into())]),
763 TypeDefinitionKind::anonymous([Constraint::precision(3.into()), Constraint::type_constraint(34)])
764 ),
765 case::scale_constraint(
766 anonymous_type([scale(2.into())]),
770 TypeDefinitionKind::anonymous([Constraint::scale(2.into()), Constraint::type_constraint(34)])
771 ),
772 case::exponent_constraint(
773 isl_type::v_2_0::anonymous_type([isl_constraint::v_2_0::exponent(2.into())]),
777 TypeDefinitionKind::anonymous([Constraint::exponent(2.into()), Constraint::type_constraint(34)])
778 ),
779 case::timestamp_precision_constraint(
780 anonymous_type([timestamp_precision(TimestampPrecisionRange::new_single_value(TimestampPrecision::Month))]),
784 TypeDefinitionKind::anonymous([Constraint::timestamp_precision(TimestampPrecision::Month.into()), Constraint::type_constraint(34)])
785 ),
786 case::valid_values_constraint(
787 anonymous_type([valid_values(vec![2.into(), ion_rs::Decimal::new(35, -1).into(), 5e7.into(), "hello".to_owned().into(), Symbol::from("hi").into(), NumberRange::new_inclusive(2.into(), 3.into()).unwrap().into()]).unwrap()]),
791 TypeDefinitionKind::anonymous([Constraint::valid_values(vec![2.into(), ion_rs::Decimal::new(35, -1).into(), 5e7.into(), "hello".to_owned().into(), Symbol::from("hi").into(), NumberRange::new_inclusive(2.into(), 3.into()).unwrap().into()], IslVersion::V1_0).unwrap(), Constraint::type_constraint(34)])
792 ),
793 case::utf8_byte_length_constraint(
794 anonymous_type([utf8_byte_length(3.into())]),
798 TypeDefinitionKind::anonymous([Constraint::utf8_byte_length(3.into()), Constraint::type_constraint(34)])
799 ),
800 case::regex_constraint(
801 anonymous_type(
805 [regex(
806 false, false, "[abc]".to_string()
809 )]
810 ),
811 TypeDefinitionKind::anonymous([
812 Constraint::regex(
813 false, false, "[abc]".to_string(),
816 IslVersion::V1_0
817 ).unwrap(),
818 Constraint::type_constraint(34)
819 ])
820 ),
821 case::timestamp_offset_constraint(
822 anonymous_type(
826 [timestamp_offset(vec!["-00:00".try_into().unwrap()])]
827 ),
828 TypeDefinitionKind::anonymous([Constraint::timestamp_offset(vec!["-00:00".try_into().unwrap()]),
829 Constraint::type_constraint(34)
830 ])
831 ),
832 case::ieee754_float_constraint(
833 isl_type::v_2_0::anonymous_type([isl_constraint::v_2_0::ieee754_float(Ieee754InterchangeFormat::Binary16)]),
837 TypeDefinitionKind::anonymous([Constraint::ieee754_float(Ieee754InterchangeFormat::Binary16), Constraint::type_constraint(34)])
838 ),
839 )]
840 fn isl_type_to_type_definition(isl_type: IslType, type_def: TypeDefinitionKind) {
841 let type_store = &mut TypeStore::default();
843 let pending_types = &mut PendingTypes::default();
844 let this_type_def = {
845 let type_id = TypeDefinitionImpl::parse_from_isl_type_and_update_pending_types(
846 IslVersion::V1_0,
847 &isl_type,
848 type_store,
849 pending_types,
850 )
851 .unwrap();
852 pending_types
853 .update_type_store(type_store, None, &HashSet::new())
854 .unwrap();
855 type_store.get_type_by_id(type_id).unwrap()
856 };
857 assert_eq!(this_type_def, &type_def);
858 }
859}