1use super::facets::FacetSet;
6use super::{PrimitiveTypeCode, XmlTypeCode};
7use crate::ids::{NameId, SimpleTypeKey, TypeKey};
8use crate::parser::location::SourceRef;
9use crate::schema::model::DerivationSet;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13pub enum SimpleTypeVariety {
14 Atomic,
16 List,
18 Union,
20}
21
22#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
28pub enum SimpleTypeDerivationMethod {
29 #[default]
31 Restriction,
32 List,
34 Union,
36}
37
38#[derive(Debug, Clone)]
40pub enum SimpleTypeRef {
41 Resolved(SimpleTypeKey),
43 Unresolved {
45 namespace: Option<NameId>,
46 local_name: NameId,
47 },
48 BuiltIn(BuiltInType),
50}
51
52#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
58pub enum BuiltInType {
59 AnySimpleType,
62 AnyAtomicType,
64 UntypedAtomic,
66
67 String,
70 Boolean,
72 Decimal,
74 Float,
76 Double,
78 Duration,
80 DateTime,
82 Time,
84 Date,
86 GYearMonth,
88 GYear,
90 GMonthDay,
92 GDay,
94 GMonth,
96 HexBinary,
98 Base64Binary,
100 AnyURI,
102 QName,
104 NOTATION,
106
107 NormalizedString,
110 Token,
112 Language,
114 NMTOKEN,
116 NMTOKENS,
118 Name,
120 NCName,
122 ID,
124 IDREF,
126 IDREFS,
128 ENTITY,
130 ENTITIES,
132
133 Integer,
136 NonPositiveInteger,
138 NegativeInteger,
140 Long,
142 Int,
144 Short,
146 Byte,
148 NonNegativeInteger,
150 UnsignedLong,
152 UnsignedInt,
154 UnsignedShort,
156 UnsignedByte,
158 PositiveInteger,
160
161 YearMonthDuration,
164 DayTimeDuration,
166 DateTimeStamp,
168 XsError,
170}
171
172impl BuiltInType {
173 #[inline]
177 pub fn local_name(&self) -> &'static str {
178 self.type_code()
180 .local_name()
181 .expect("BuiltInType always has a local name")
182 }
183
184 #[inline]
186 pub fn type_code(&self) -> XmlTypeCode {
187 XmlTypeCode::from(*self)
188 }
189
190 #[inline]
195 pub fn primitive_type_code(&self) -> Option<PrimitiveTypeCode> {
196 PrimitiveTypeCode::from_type_code(self.type_code())
197 }
198
199 #[inline]
201 pub fn is_primitive(&self) -> bool {
202 matches!(
203 self,
204 Self::String
205 | Self::Boolean
206 | Self::Decimal
207 | Self::Float
208 | Self::Double
209 | Self::Duration
210 | Self::DateTime
211 | Self::Time
212 | Self::Date
213 | Self::GYearMonth
214 | Self::GYear
215 | Self::GMonthDay
216 | Self::GDay
217 | Self::GMonth
218 | Self::HexBinary
219 | Self::Base64Binary
220 | Self::AnyURI
221 | Self::QName
222 | Self::NOTATION
223 )
224 }
225
226 #[inline]
228 pub fn is_list(&self) -> bool {
229 matches!(self, Self::NMTOKENS | Self::IDREFS | Self::ENTITIES)
230 }
231
232 #[inline]
234 pub fn is_xsd11(&self) -> bool {
235 matches!(
236 self,
237 Self::AnyAtomicType
238 | Self::UntypedAtomic
239 | Self::YearMonthDuration
240 | Self::DayTimeDuration
241 | Self::DateTimeStamp
242 | Self::XsError
243 )
244 }
245
246 pub fn from_local_name(name: &str) -> Option<BuiltInType> {
250 XmlTypeCode::from_local_name(name).and_then(|code| Self::try_from(code).ok())
251 }
252
253 pub fn all() -> impl Iterator<Item = BuiltInType> {
255 [
256 Self::AnySimpleType,
257 Self::AnyAtomicType,
258 Self::UntypedAtomic,
259 Self::String,
260 Self::Boolean,
261 Self::Decimal,
262 Self::Float,
263 Self::Double,
264 Self::Duration,
265 Self::DateTime,
266 Self::Time,
267 Self::Date,
268 Self::GYearMonth,
269 Self::GYear,
270 Self::GMonthDay,
271 Self::GDay,
272 Self::GMonth,
273 Self::HexBinary,
274 Self::Base64Binary,
275 Self::AnyURI,
276 Self::QName,
277 Self::NOTATION,
278 Self::NormalizedString,
279 Self::Token,
280 Self::Language,
281 Self::NMTOKEN,
282 Self::NMTOKENS,
283 Self::Name,
284 Self::NCName,
285 Self::ID,
286 Self::IDREF,
287 Self::IDREFS,
288 Self::ENTITY,
289 Self::ENTITIES,
290 Self::Integer,
291 Self::NonPositiveInteger,
292 Self::NegativeInteger,
293 Self::Long,
294 Self::Int,
295 Self::Short,
296 Self::Byte,
297 Self::NonNegativeInteger,
298 Self::UnsignedLong,
299 Self::UnsignedInt,
300 Self::UnsignedShort,
301 Self::UnsignedByte,
302 Self::PositiveInteger,
303 Self::YearMonthDuration,
304 Self::DayTimeDuration,
305 Self::DateTimeStamp,
306 Self::XsError,
307 ]
308 .into_iter()
309 }
310}
311
312impl From<BuiltInType> for XmlTypeCode {
317 fn from(builtin: BuiltInType) -> Self {
318 match builtin {
319 BuiltInType::AnySimpleType => XmlTypeCode::AnySimpleType,
320 BuiltInType::AnyAtomicType => XmlTypeCode::AnyAtomicType,
321 BuiltInType::UntypedAtomic => XmlTypeCode::UntypedAtomic,
322 BuiltInType::String => XmlTypeCode::String,
323 BuiltInType::Boolean => XmlTypeCode::Boolean,
324 BuiltInType::Decimal => XmlTypeCode::Decimal,
325 BuiltInType::Float => XmlTypeCode::Float,
326 BuiltInType::Double => XmlTypeCode::Double,
327 BuiltInType::Duration => XmlTypeCode::Duration,
328 BuiltInType::DateTime => XmlTypeCode::DateTime,
329 BuiltInType::Time => XmlTypeCode::Time,
330 BuiltInType::Date => XmlTypeCode::Date,
331 BuiltInType::GYearMonth => XmlTypeCode::GYearMonth,
332 BuiltInType::GYear => XmlTypeCode::GYear,
333 BuiltInType::GMonthDay => XmlTypeCode::GMonthDay,
334 BuiltInType::GDay => XmlTypeCode::GDay,
335 BuiltInType::GMonth => XmlTypeCode::GMonth,
336 BuiltInType::HexBinary => XmlTypeCode::HexBinary,
337 BuiltInType::Base64Binary => XmlTypeCode::Base64Binary,
338 BuiltInType::AnyURI => XmlTypeCode::AnyUri,
339 BuiltInType::QName => XmlTypeCode::QName,
340 BuiltInType::NOTATION => XmlTypeCode::Notation,
341 BuiltInType::NormalizedString => XmlTypeCode::NormalizedString,
342 BuiltInType::Token => XmlTypeCode::Token,
343 BuiltInType::Language => XmlTypeCode::Language,
344 BuiltInType::NMTOKEN => XmlTypeCode::NmToken,
345 BuiltInType::NMTOKENS => XmlTypeCode::NmTokens,
346 BuiltInType::Name => XmlTypeCode::Name,
347 BuiltInType::NCName => XmlTypeCode::NCName,
348 BuiltInType::ID => XmlTypeCode::Id,
349 BuiltInType::IDREF => XmlTypeCode::IdRef,
350 BuiltInType::IDREFS => XmlTypeCode::IdRefs,
351 BuiltInType::ENTITY => XmlTypeCode::Entity,
352 BuiltInType::ENTITIES => XmlTypeCode::Entities,
353 BuiltInType::Integer => XmlTypeCode::Integer,
354 BuiltInType::NonPositiveInteger => XmlTypeCode::NonPositiveInteger,
355 BuiltInType::NegativeInteger => XmlTypeCode::NegativeInteger,
356 BuiltInType::Long => XmlTypeCode::Long,
357 BuiltInType::Int => XmlTypeCode::Int,
358 BuiltInType::Short => XmlTypeCode::Short,
359 BuiltInType::Byte => XmlTypeCode::Byte,
360 BuiltInType::NonNegativeInteger => XmlTypeCode::NonNegativeInteger,
361 BuiltInType::UnsignedLong => XmlTypeCode::UnsignedLong,
362 BuiltInType::UnsignedInt => XmlTypeCode::UnsignedInt,
363 BuiltInType::UnsignedShort => XmlTypeCode::UnsignedShort,
364 BuiltInType::UnsignedByte => XmlTypeCode::UnsignedByte,
365 BuiltInType::PositiveInteger => XmlTypeCode::PositiveInteger,
366 BuiltInType::YearMonthDuration => XmlTypeCode::YearMonthDuration,
367 BuiltInType::DayTimeDuration => XmlTypeCode::DayTimeDuration,
368 BuiltInType::DateTimeStamp => XmlTypeCode::DateTimeStamp,
369 BuiltInType::XsError => XmlTypeCode::Error,
370 }
371 }
372}
373
374impl TryFrom<XmlTypeCode> for BuiltInType {
375 type Error = ();
376
377 fn try_from(code: XmlTypeCode) -> Result<Self, Self::Error> {
381 match code {
382 XmlTypeCode::AnySimpleType => Ok(BuiltInType::AnySimpleType),
383 XmlTypeCode::AnyAtomicType => Ok(BuiltInType::AnyAtomicType),
384 XmlTypeCode::UntypedAtomic => Ok(BuiltInType::UntypedAtomic),
385 XmlTypeCode::String => Ok(BuiltInType::String),
386 XmlTypeCode::Boolean => Ok(BuiltInType::Boolean),
387 XmlTypeCode::Decimal => Ok(BuiltInType::Decimal),
388 XmlTypeCode::Float => Ok(BuiltInType::Float),
389 XmlTypeCode::Double => Ok(BuiltInType::Double),
390 XmlTypeCode::Duration => Ok(BuiltInType::Duration),
391 XmlTypeCode::DateTime => Ok(BuiltInType::DateTime),
392 XmlTypeCode::Time => Ok(BuiltInType::Time),
393 XmlTypeCode::Date => Ok(BuiltInType::Date),
394 XmlTypeCode::GYearMonth => Ok(BuiltInType::GYearMonth),
395 XmlTypeCode::GYear => Ok(BuiltInType::GYear),
396 XmlTypeCode::GMonthDay => Ok(BuiltInType::GMonthDay),
397 XmlTypeCode::GDay => Ok(BuiltInType::GDay),
398 XmlTypeCode::GMonth => Ok(BuiltInType::GMonth),
399 XmlTypeCode::HexBinary => Ok(BuiltInType::HexBinary),
400 XmlTypeCode::Base64Binary => Ok(BuiltInType::Base64Binary),
401 XmlTypeCode::AnyUri => Ok(BuiltInType::AnyURI),
402 XmlTypeCode::QName => Ok(BuiltInType::QName),
403 XmlTypeCode::Notation => Ok(BuiltInType::NOTATION),
404 XmlTypeCode::NormalizedString => Ok(BuiltInType::NormalizedString),
405 XmlTypeCode::Token => Ok(BuiltInType::Token),
406 XmlTypeCode::Language => Ok(BuiltInType::Language),
407 XmlTypeCode::NmToken => Ok(BuiltInType::NMTOKEN),
408 XmlTypeCode::NmTokens => Ok(BuiltInType::NMTOKENS),
409 XmlTypeCode::Name => Ok(BuiltInType::Name),
410 XmlTypeCode::NCName => Ok(BuiltInType::NCName),
411 XmlTypeCode::Id => Ok(BuiltInType::ID),
412 XmlTypeCode::IdRef => Ok(BuiltInType::IDREF),
413 XmlTypeCode::IdRefs => Ok(BuiltInType::IDREFS),
414 XmlTypeCode::Entity => Ok(BuiltInType::ENTITY),
415 XmlTypeCode::Entities => Ok(BuiltInType::ENTITIES),
416 XmlTypeCode::Integer => Ok(BuiltInType::Integer),
417 XmlTypeCode::NonPositiveInteger => Ok(BuiltInType::NonPositiveInteger),
418 XmlTypeCode::NegativeInteger => Ok(BuiltInType::NegativeInteger),
419 XmlTypeCode::Long => Ok(BuiltInType::Long),
420 XmlTypeCode::Int => Ok(BuiltInType::Int),
421 XmlTypeCode::Short => Ok(BuiltInType::Short),
422 XmlTypeCode::Byte => Ok(BuiltInType::Byte),
423 XmlTypeCode::NonNegativeInteger => Ok(BuiltInType::NonNegativeInteger),
424 XmlTypeCode::UnsignedLong => Ok(BuiltInType::UnsignedLong),
425 XmlTypeCode::UnsignedInt => Ok(BuiltInType::UnsignedInt),
426 XmlTypeCode::UnsignedShort => Ok(BuiltInType::UnsignedShort),
427 XmlTypeCode::UnsignedByte => Ok(BuiltInType::UnsignedByte),
428 XmlTypeCode::PositiveInteger => Ok(BuiltInType::PositiveInteger),
429 XmlTypeCode::YearMonthDuration => Ok(BuiltInType::YearMonthDuration),
430 XmlTypeCode::DayTimeDuration => Ok(BuiltInType::DayTimeDuration),
431 XmlTypeCode::DateTimeStamp => Ok(BuiltInType::DateTimeStamp),
432 XmlTypeCode::Error => Ok(BuiltInType::XsError),
433 _ => Err(()),
435 }
436 }
437}
438
439#[derive(Debug, Clone)]
444pub struct SimpleTypeDef {
445 pub name: Option<NameId>,
447
448 pub target_namespace: Option<NameId>,
450
451 pub source: Option<SourceRef>,
453
454 pub variety: SimpleTypeVariety,
456
457 pub derivation_method: SimpleTypeDerivationMethod,
459
460 pub base_type: Option<SimpleTypeRef>,
462
463 pub item_type: Option<SimpleTypeRef>,
465
466 pub member_types: Vec<SimpleTypeRef>,
468
469 pub facets: FacetSet,
471
472 pub type_code: XmlTypeCode,
478
479 pub primitive_type: Option<PrimitiveTypeCode>,
485
486 pub final_derivation: DerivationSet,
488
489 pub id: Option<String>,
491}
492
493impl SimpleTypeDef {
494 pub fn new_restriction(
496 name: Option<NameId>,
497 target_namespace: Option<NameId>,
498 base_type: SimpleTypeRef,
499 ) -> Self {
500 Self {
501 name,
502 target_namespace,
503 source: None,
504 variety: SimpleTypeVariety::Atomic,
505 derivation_method: SimpleTypeDerivationMethod::Restriction,
506 base_type: Some(base_type),
507 item_type: None,
508 member_types: Vec::new(),
509 facets: FacetSet::new(),
510 type_code: XmlTypeCode::None,
511 primitive_type: None,
512 final_derivation: DerivationSet::empty(),
513 id: None,
514 }
515 }
516
517 pub fn new_list(
519 name: Option<NameId>,
520 target_namespace: Option<NameId>,
521 item_type: SimpleTypeRef,
522 ) -> Self {
523 Self {
524 name,
525 target_namespace,
526 source: None,
527 variety: SimpleTypeVariety::List,
528 derivation_method: SimpleTypeDerivationMethod::List,
529 base_type: None,
530 item_type: Some(item_type),
531 member_types: Vec::new(),
532 facets: FacetSet::new(),
533 type_code: XmlTypeCode::None,
534 primitive_type: None, final_derivation: DerivationSet::empty(),
536 id: None,
537 }
538 }
539
540 pub fn new_union(
542 name: Option<NameId>,
543 target_namespace: Option<NameId>,
544 member_types: Vec<SimpleTypeRef>,
545 ) -> Self {
546 Self {
547 name,
548 target_namespace,
549 source: None,
550 variety: SimpleTypeVariety::Union,
551 derivation_method: SimpleTypeDerivationMethod::Union,
552 base_type: None,
553 item_type: None,
554 member_types,
555 facets: FacetSet::new(),
556 type_code: XmlTypeCode::None,
557 primitive_type: None, final_derivation: DerivationSet::empty(),
559 id: None,
560 }
561 }
562
563 pub fn new_builtin(
568 name: NameId,
569 target_namespace: Option<NameId>,
570 builtin: BuiltInType,
571 ) -> Self {
572 let type_code = builtin.type_code();
573 let primitive_type = builtin.primitive_type_code();
574 let variety = if builtin.is_list() {
575 SimpleTypeVariety::List
576 } else {
577 SimpleTypeVariety::Atomic
578 };
579 let derivation_method = if builtin.is_list() {
580 SimpleTypeDerivationMethod::List
581 } else {
582 SimpleTypeDerivationMethod::Restriction
583 };
584
585 Self {
586 name: Some(name),
587 target_namespace,
588 source: None,
589 variety,
590 derivation_method,
591 base_type: None, item_type: None, member_types: Vec::new(),
594 facets: default_facets_for_builtin(builtin),
595 type_code,
596 primitive_type,
597 final_derivation: DerivationSet::empty(),
598 id: None,
599 }
600 }
601
602 pub fn is_anonymous(&self) -> bool {
604 self.name.is_none()
605 }
606
607 pub fn is_global(&self) -> bool {
609 self.name.is_some()
610 }
611
612 pub fn is_atomic(&self) -> bool {
614 self.variety == SimpleTypeVariety::Atomic
615 }
616
617 pub fn is_list(&self) -> bool {
619 self.variety == SimpleTypeVariety::List
620 }
621
622 pub fn is_union(&self) -> bool {
624 self.variety == SimpleTypeVariety::Union
625 }
626
627 pub fn is_restriction(&self) -> bool {
629 self.derivation_method == SimpleTypeDerivationMethod::Restriction
630 }
631
632 pub fn get_primitive_type(&self) -> Option<PrimitiveTypeCode> {
637 self.primitive_type
638 }
639
640 pub fn get_type_code(&self) -> XmlTypeCode {
642 self.type_code
643 }
644
645 pub fn type_key(&self, key: SimpleTypeKey) -> TypeKey {
647 TypeKey::Simple(key)
648 }
649}
650
651pub fn default_facets_for_builtin(builtin: BuiltInType) -> FacetSet {
655 effective_arena_facets_for_builtin(builtin)
656}
657
658pub fn effective_arena_facets_for_builtin(builtin: BuiltInType) -> FacetSet {
665 use super::facets::{FacetFixed, WhitespaceMode};
666
667 let mut facets = FacetSet::new();
668
669 match builtin {
673 BuiltInType::String => {
674 facets.set_whitespace(WhitespaceMode::Preserve, FacetFixed::Default, None);
675 }
676 BuiltInType::NormalizedString => {
677 facets.set_whitespace(WhitespaceMode::Replace, FacetFixed::Default, None);
678 }
679 BuiltInType::AnySimpleType | BuiltInType::AnyAtomicType | BuiltInType::XsError => {}
680 _ => {
681 facets.set_whitespace(WhitespaceMode::Collapse, FacetFixed::Fixed, None);
682 }
683 }
684
685 if let Some((lo, hi)) = integer_hierarchy_bounds(builtin) {
686 facets.set_fraction_digits(0, FacetFixed::Fixed, None);
687 if let Some(v) = lo {
688 facets.set_min_inclusive(v, FacetFixed::Default, None);
689 }
690 if let Some(v) = hi {
691 facets.set_max_inclusive(v, FacetFixed::Default, None);
692 }
693 }
694
695 if matches!(
696 builtin,
697 BuiltInType::IDREFS | BuiltInType::NMTOKENS | BuiltInType::ENTITIES
698 ) {
699 facets.set_min_length(1, FacetFixed::Default, None);
700 }
701
702 facets
703}
704
705fn integer_hierarchy_bounds(builtin: BuiltInType) -> Option<(Option<String>, Option<String>)> {
709 let bounds = match builtin {
710 BuiltInType::Integer => (None, None),
711 BuiltInType::NonPositiveInteger => (None, Some("0".to_string())),
712 BuiltInType::NegativeInteger => (None, Some("-1".to_string())),
713 BuiltInType::NonNegativeInteger => (Some("0".to_string()), None),
714 BuiltInType::PositiveInteger => (Some("1".to_string()), None),
715 BuiltInType::Long => (Some(i64::MIN.to_string()), Some(i64::MAX.to_string())),
716 BuiltInType::Int => (Some(i32::MIN.to_string()), Some(i32::MAX.to_string())),
717 BuiltInType::Short => (Some(i16::MIN.to_string()), Some(i16::MAX.to_string())),
718 BuiltInType::Byte => (Some(i8::MIN.to_string()), Some(i8::MAX.to_string())),
719 BuiltInType::UnsignedLong => (Some("0".to_string()), Some(u64::MAX.to_string())),
720 BuiltInType::UnsignedInt => (Some("0".to_string()), Some(u32::MAX.to_string())),
721 BuiltInType::UnsignedShort => (Some("0".to_string()), Some(u16::MAX.to_string())),
722 BuiltInType::UnsignedByte => (Some("0".to_string()), Some(u8::MAX.to_string())),
723 _ => return None,
724 };
725 Some(bounds)
726}
727
728#[cfg(test)]
729mod tests {
730 use super::*;
731
732 #[test]
733 fn test_builtin_type_names() {
734 assert_eq!(BuiltInType::String.local_name(), "string");
735 assert_eq!(BuiltInType::Integer.local_name(), "integer");
736 assert_eq!(BuiltInType::DateTime.local_name(), "dateTime");
737 assert_eq!(BuiltInType::AnyURI.local_name(), "anyURI");
738 assert_eq!(BuiltInType::NMTOKEN.local_name(), "NMTOKEN");
739 assert_eq!(BuiltInType::UntypedAtomic.local_name(), "untypedAtomic");
740 assert_eq!(
741 BuiltInType::YearMonthDuration.local_name(),
742 "yearMonthDuration"
743 );
744 }
745
746 #[test]
747 fn test_builtin_type_parsing() {
748 assert_eq!(
749 BuiltInType::from_local_name("string"),
750 Some(BuiltInType::String)
751 );
752 assert_eq!(
753 BuiltInType::from_local_name("integer"),
754 Some(BuiltInType::Integer)
755 );
756 assert_eq!(
757 BuiltInType::from_local_name("untypedAtomic"),
758 Some(BuiltInType::UntypedAtomic)
759 );
760 assert_eq!(
761 BuiltInType::from_local_name("yearMonthDuration"),
762 Some(BuiltInType::YearMonthDuration)
763 );
764 assert_eq!(BuiltInType::from_local_name("nonExistent"), None);
765 assert_eq!(BuiltInType::from_local_name("anyType"), None);
767 }
768
769 #[test]
770 fn test_builtin_is_primitive() {
771 assert!(BuiltInType::String.is_primitive());
772 assert!(BuiltInType::Decimal.is_primitive());
773 assert!(BuiltInType::Duration.is_primitive());
774 assert!(!BuiltInType::Integer.is_primitive()); assert!(!BuiltInType::NCName.is_primitive()); assert!(!BuiltInType::AnySimpleType.is_primitive()); assert!(!BuiltInType::NMTOKENS.is_primitive()); }
779
780 #[test]
781 fn test_builtin_is_list() {
782 assert!(BuiltInType::NMTOKENS.is_list());
783 assert!(BuiltInType::IDREFS.is_list());
784 assert!(BuiltInType::ENTITIES.is_list());
785 assert!(!BuiltInType::NMTOKEN.is_list());
786 assert!(!BuiltInType::String.is_list());
787 }
788
789 #[test]
790 fn test_builtin_is_xsd11() {
791 assert!(BuiltInType::AnyAtomicType.is_xsd11());
792 assert!(BuiltInType::UntypedAtomic.is_xsd11());
793 assert!(BuiltInType::YearMonthDuration.is_xsd11());
794 assert!(BuiltInType::DayTimeDuration.is_xsd11());
795 assert!(BuiltInType::DateTimeStamp.is_xsd11());
796 assert!(!BuiltInType::String.is_xsd11());
797 assert!(!BuiltInType::DateTime.is_xsd11());
798 }
799
800 #[test]
801 fn test_builtin_type_code() {
802 assert_eq!(BuiltInType::String.type_code(), XmlTypeCode::String);
803 assert_eq!(BuiltInType::Integer.type_code(), XmlTypeCode::Integer);
804 assert_eq!(BuiltInType::NMTOKEN.type_code(), XmlTypeCode::NmToken);
805 assert_eq!(BuiltInType::AnyURI.type_code(), XmlTypeCode::AnyUri);
806 }
807
808 #[test]
809 fn test_builtin_primitive_type_code() {
810 assert_eq!(
811 BuiltInType::String.primitive_type_code(),
812 Some(PrimitiveTypeCode::String)
813 );
814 assert_eq!(
815 BuiltInType::NCName.primitive_type_code(),
816 Some(PrimitiveTypeCode::String)
817 );
818 assert_eq!(
819 BuiltInType::Integer.primitive_type_code(),
820 Some(PrimitiveTypeCode::Decimal)
821 );
822 assert_eq!(
823 BuiltInType::Duration.primitive_type_code(),
824 Some(PrimitiveTypeCode::Duration)
825 );
826 assert_eq!(
827 BuiltInType::YearMonthDuration.primitive_type_code(),
828 Some(PrimitiveTypeCode::Duration)
829 );
830 assert_eq!(BuiltInType::AnySimpleType.primitive_type_code(), None);
832 assert_eq!(BuiltInType::NMTOKENS.primitive_type_code(), None);
833 }
834
835 #[test]
836 fn test_builtin_to_xml_type_code_conversion() {
837 assert_eq!(XmlTypeCode::from(BuiltInType::String), XmlTypeCode::String);
839 assert_eq!(
840 XmlTypeCode::from(BuiltInType::NOTATION),
841 XmlTypeCode::Notation
842 );
843 assert_eq!(XmlTypeCode::from(BuiltInType::AnyURI), XmlTypeCode::AnyUri);
844 assert_eq!(
845 XmlTypeCode::from(BuiltInType::NMTOKEN),
846 XmlTypeCode::NmToken
847 );
848 }
849
850 #[test]
851 fn test_xml_type_code_to_builtin_conversion() {
852 assert_eq!(
854 BuiltInType::try_from(XmlTypeCode::String),
855 Ok(BuiltInType::String)
856 );
857 assert_eq!(
858 BuiltInType::try_from(XmlTypeCode::Notation),
859 Ok(BuiltInType::NOTATION)
860 );
861 assert_eq!(
862 BuiltInType::try_from(XmlTypeCode::AnyUri),
863 Ok(BuiltInType::AnyURI)
864 );
865 assert_eq!(
866 BuiltInType::try_from(XmlTypeCode::NmToken),
867 Ok(BuiltInType::NMTOKEN)
868 );
869
870 assert!(BuiltInType::try_from(XmlTypeCode::None).is_err());
872 assert!(BuiltInType::try_from(XmlTypeCode::Element).is_err());
873 assert!(BuiltInType::try_from(XmlTypeCode::AnyType).is_err());
874 }
875
876 #[test]
877 fn test_builtin_roundtrip_conversion() {
878 for builtin in BuiltInType::all() {
880 let code = XmlTypeCode::from(builtin);
881 let back = BuiltInType::try_from(code).expect("Should convert back");
882 assert_eq!(back, builtin, "Roundtrip failed for {:?}", builtin);
883 }
884 }
885
886 #[test]
887 fn test_builtin_all_count() {
888 assert_eq!(BuiltInType::all().count(), 51);
889 }
890
891 #[test]
892 fn test_simple_type_restriction() {
893 let st = SimpleTypeDef::new_restriction(
894 Some(NameId(1)),
895 Some(NameId(2)),
896 SimpleTypeRef::BuiltIn(BuiltInType::String),
897 );
898
899 assert_eq!(st.variety, SimpleTypeVariety::Atomic);
900 assert_eq!(
901 st.derivation_method,
902 SimpleTypeDerivationMethod::Restriction
903 );
904 assert!(st.is_global());
905 assert!(st.is_atomic());
906 assert!(st.is_restriction());
907 assert!(st.base_type.is_some());
908 assert_eq!(st.type_code, XmlTypeCode::None); assert!(st.primitive_type.is_none()); }
911
912 #[test]
913 fn test_simple_type_list() {
914 let st = SimpleTypeDef::new_list(None, None, SimpleTypeRef::BuiltIn(BuiltInType::Integer));
915
916 assert_eq!(st.variety, SimpleTypeVariety::List);
917 assert_eq!(st.derivation_method, SimpleTypeDerivationMethod::List);
918 assert!(st.is_anonymous());
919 assert!(st.is_list());
920 assert!(st.item_type.is_some());
921 assert!(st.primitive_type.is_none()); }
923
924 #[test]
925 fn test_simple_type_union() {
926 let st = SimpleTypeDef::new_union(
927 Some(NameId(1)),
928 None,
929 vec![
930 SimpleTypeRef::BuiltIn(BuiltInType::String),
931 SimpleTypeRef::BuiltIn(BuiltInType::Integer),
932 ],
933 );
934
935 assert_eq!(st.variety, SimpleTypeVariety::Union);
936 assert_eq!(st.derivation_method, SimpleTypeDerivationMethod::Union);
937 assert!(st.is_union());
938 assert_eq!(st.member_types.len(), 2);
939 assert!(st.primitive_type.is_none()); }
941
942 #[test]
943 fn test_simple_type_builtin_atomic() {
944 let st = SimpleTypeDef::new_builtin(NameId(1), Some(NameId(2)), BuiltInType::String);
945
946 assert_eq!(st.variety, SimpleTypeVariety::Atomic);
947 assert_eq!(
948 st.derivation_method,
949 SimpleTypeDerivationMethod::Restriction
950 );
951 assert!(st.is_atomic());
952 assert_eq!(st.type_code, XmlTypeCode::String);
953 assert_eq!(st.primitive_type, Some(PrimitiveTypeCode::String));
954 }
955
956 #[test]
957 fn test_simple_type_builtin_list() {
958 let st = SimpleTypeDef::new_builtin(NameId(1), Some(NameId(2)), BuiltInType::NMTOKENS);
959
960 assert_eq!(st.variety, SimpleTypeVariety::List);
961 assert_eq!(st.derivation_method, SimpleTypeDerivationMethod::List);
962 assert!(st.is_list());
963 assert_eq!(st.type_code, XmlTypeCode::NmTokens);
964 assert!(st.primitive_type.is_none()); }
966
967 #[test]
968 fn test_simple_type_builtin_derived() {
969 let st = SimpleTypeDef::new_builtin(NameId(1), Some(NameId(2)), BuiltInType::Integer);
971
972 assert_eq!(st.type_code, XmlTypeCode::Integer);
973 assert_eq!(st.primitive_type, Some(PrimitiveTypeCode::Decimal));
974 }
975
976 #[test]
977 fn test_simple_type_derivation_method_default() {
978 assert_eq!(
979 SimpleTypeDerivationMethod::default(),
980 SimpleTypeDerivationMethod::Restriction
981 );
982 }
983
984 #[test]
985 fn test_simple_type_variety_copy() {
986 let variety = SimpleTypeVariety::Atomic;
987 let copy = variety;
988 assert_eq!(variety, copy);
989 }
990
991 #[test]
992 fn test_default_facets() {
993 let string_facets = default_facets_for_builtin(BuiltInType::String);
994 assert!(string_facets.whitespace.is_some());
995
996 let int_facets = default_facets_for_builtin(BuiltInType::Integer);
997 assert!(int_facets.whitespace.is_some());
998 }
999
1000 #[test]
1001 fn test_simple_type_helper_methods() {
1002 let restriction = SimpleTypeDef::new_restriction(
1003 Some(NameId(1)),
1004 None,
1005 SimpleTypeRef::BuiltIn(BuiltInType::String),
1006 );
1007 assert!(restriction.is_atomic());
1008 assert!(!restriction.is_list());
1009 assert!(!restriction.is_union());
1010 assert!(restriction.is_restriction());
1011
1012 let list = SimpleTypeDef::new_list(None, None, SimpleTypeRef::BuiltIn(BuiltInType::String));
1013 assert!(!list.is_atomic());
1014 assert!(list.is_list());
1015 assert!(!list.is_union());
1016
1017 let union = SimpleTypeDef::new_union(
1018 None,
1019 None,
1020 vec![SimpleTypeRef::BuiltIn(BuiltInType::String)],
1021 );
1022 assert!(!union.is_atomic());
1023 assert!(!union.is_list());
1024 assert!(union.is_union());
1025 }
1026
1027 #[test]
1028 fn test_simple_type_get_type_code() {
1029 let st = SimpleTypeDef::new_builtin(NameId(1), None, BuiltInType::DateTime);
1030 assert_eq!(st.get_type_code(), XmlTypeCode::DateTime);
1031 }
1032
1033 #[test]
1034 fn test_simple_type_get_primitive_type() {
1035 let st = SimpleTypeDef::new_builtin(NameId(1), None, BuiltInType::NCName);
1036 assert_eq!(st.get_primitive_type(), Some(PrimitiveTypeCode::String));
1037
1038 let list_st = SimpleTypeDef::new_builtin(NameId(2), None, BuiltInType::IDREFS);
1039 assert_eq!(list_st.get_primitive_type(), None);
1040 }
1041}