@@ -20,18 +20,6 @@ type Result<T> = PyResult<T>;
2020
2121static TAGGED_CLASS : GILOnceCell < Py < PyAny > > = GILOnceCell :: new ( ) ;
2222
23- #[ derive( Copy , Clone , PartialEq , Eq , Debug ) ]
24- enum CanonicalTagKind {
25- CoreString ,
26- CoreNull ,
27- }
28-
29- enum TagClass {
30- Canonical ( CanonicalTagKind ) ,
31- Core ,
32- NonCore ,
33- }
34-
3523#[ derive( Clone , PartialEq , Eq , Hash ) ]
3624struct HandlerKeyOwned {
3725 handle : String ,
@@ -448,23 +436,19 @@ fn resolve_representation(node: &mut Yaml, _simplify: bool) {
448436 let parsed = match tag {
449437 Some ( tag) => {
450438 let owned_tag = tag. into_owned ( ) ;
451- match classify_tag ( & owned_tag) {
452- TagClass :: Canonical ( kind) => {
453- if kind == CanonicalTagKind :: CoreNull && is_plain_empty {
454- Yaml :: Value ( Scalar :: Null )
455- } else {
456- let canonical_tag = Cow :: Owned ( make_canonical_tag ( kind) ) ;
457- Yaml :: value_from_cow_and_metadata ( value, style, Some ( & canonical_tag) )
458- }
459- }
460- TagClass :: Core => {
461- let core_tag = Cow :: Owned ( owned_tag) ;
462- Yaml :: value_from_cow_and_metadata ( value, style, Some ( & core_tag) )
463- }
464- TagClass :: NonCore => Yaml :: Tagged (
439+ if is_canonical_null_tag ( & owned_tag) && is_plain_empty {
440+ Yaml :: Value ( Scalar :: Null )
441+ } else if let Some ( canonical) = canonicalize_tag ( & owned_tag) {
442+ let canonical_tag = Cow :: Owned ( canonical) ;
443+ Yaml :: value_from_cow_and_metadata ( value, style, Some ( & canonical_tag) )
444+ } else if is_core_tag ( & owned_tag) {
445+ let core_tag = Cow :: Owned ( owned_tag) ;
446+ Yaml :: value_from_cow_and_metadata ( value, style, Some ( & core_tag) )
447+ } else {
448+ Yaml :: Tagged (
465449 Cow :: Owned ( owned_tag) ,
466450 Box :: new ( Yaml :: Value ( Scalar :: String ( value) ) ) ,
467- ) ,
451+ )
468452 }
469453 }
470454 None if is_plain_empty => Yaml :: Value ( Scalar :: Null ) ,
@@ -580,13 +564,12 @@ fn convert_tagged(
580564 return registry. apply ( py, handler, value) ;
581565 }
582566 }
583- match classify_tag ( tag) {
584- TagClass :: Canonical ( _) | TagClass :: Core => yaml_to_py ( py, node, is_key, handlers) ,
585- TagClass :: NonCore => {
586- let value = yaml_to_py ( py, node, is_key, handlers) ?;
587- let rendered = render_tag ( tag) ;
588- make_tagged ( py, value, & rendered)
589- }
567+ if is_core_tag ( tag) {
568+ yaml_to_py ( py, node, is_key, handlers)
569+ } else {
570+ let value = yaml_to_py ( py, node, is_key, handlers) ?;
571+ let rendered = render_tag ( tag) ;
572+ make_tagged ( py, value, & rendered)
590573 }
591574}
592575
@@ -597,42 +580,47 @@ fn make_tagged(py: Python<'_>, value: PyObject, tag: &str) -> Result<PyObject> {
597580 cls. bind ( py) . call1 ( ( value, tag) ) . map ( |obj| obj. into ( ) )
598581}
599582
600- fn canonical_tag_kind ( tag : & Tag ) -> Option < CanonicalTagKind > {
601- match ( tag. handle . as_str ( ) , tag. suffix . as_str ( ) ) {
602- ( "tag:yaml.org,2002:" , "str" ) => Some ( CanonicalTagKind :: CoreString ) ,
603- ( "!" , "str" ) => Some ( CanonicalTagKind :: CoreString ) ,
604- ( "" , "str" ) => Some ( CanonicalTagKind :: CoreString ) ,
605- ( "" , "!str" ) => Some ( CanonicalTagKind :: CoreString ) ,
606- ( "" , "!!str" ) => Some ( CanonicalTagKind :: CoreString ) ,
607- ( "" , "tag:yaml.org,2002:str" ) => Some ( CanonicalTagKind :: CoreString ) ,
608- ( "tag:yaml.org,2002:" , "null" ) => Some ( CanonicalTagKind :: CoreNull ) ,
609- ( "" , "null" ) => Some ( CanonicalTagKind :: CoreNull ) ,
610- ( "" , "!null" ) => Some ( CanonicalTagKind :: CoreNull ) ,
611- ( "" , "!!null" ) => Some ( CanonicalTagKind :: CoreNull ) ,
612- ( "" , "tag:yaml.org,2002:null" ) => Some ( CanonicalTagKind :: CoreNull ) ,
613- _ => None ,
614- }
615- }
616-
617- fn classify_tag ( tag : & Tag ) -> TagClass {
618- if let Some ( kind) = canonical_tag_kind ( tag) {
619- TagClass :: Canonical ( kind)
620- } else if tag. is_yaml_core_schema ( ) {
621- TagClass :: Core
583+ fn is_canonical_string_tag ( tag : & Tag ) -> bool {
584+ matches ! (
585+ ( tag. handle. as_str( ) , tag. suffix. as_str( ) ) ,
586+ ( "tag:yaml.org,2002:" , "str" )
587+ | ( "!" , "str" )
588+ | ( "" , "str" )
589+ | ( "" , "!str" )
590+ | ( "" , "!!str" )
591+ | ( "" , "tag:yaml.org,2002:str" )
592+ )
593+ }
594+
595+ fn is_canonical_null_tag ( tag : & Tag ) -> bool {
596+ matches ! (
597+ ( tag. handle. as_str( ) , tag. suffix. as_str( ) ) ,
598+ ( "tag:yaml.org,2002:" , "null" )
599+ | ( "" , "null" )
600+ | ( "" , "!null" )
601+ | ( "" , "!!null" )
602+ | ( "" , "tag:yaml.org,2002:null" )
603+ )
604+ }
605+
606+ fn canonicalize_tag ( tag : & Tag ) -> Option < Tag > {
607+ if is_canonical_string_tag ( tag) {
608+ Some ( Tag {
609+ handle : "tag:yaml.org,2002:" . to_string ( ) ,
610+ suffix : "str" . to_string ( ) ,
611+ } )
612+ } else if is_canonical_null_tag ( tag) {
613+ Some ( Tag {
614+ handle : "tag:yaml.org,2002:" . to_string ( ) ,
615+ suffix : "null" . to_string ( ) ,
616+ } )
622617 } else {
623- TagClass :: NonCore
618+ None
624619 }
625620}
626621
627- fn make_canonical_tag ( kind : CanonicalTagKind ) -> Tag {
628- let suffix = match kind {
629- CanonicalTagKind :: CoreString => "str" ,
630- CanonicalTagKind :: CoreNull => "null" ,
631- } ;
632- Tag {
633- handle : "tag:yaml.org,2002:" . to_string ( ) ,
634- suffix : suffix. to_string ( ) ,
635- }
622+ fn is_core_tag ( tag : & Tag ) -> bool {
623+ tag. is_yaml_core_schema ( ) || is_canonical_string_tag ( tag) || is_canonical_null_tag ( tag)
636624}
637625
638626fn render_tag ( tag : & Tag ) -> String {
@@ -735,9 +723,10 @@ fn py_to_yaml(py: Python<'_>, obj: &Bound<'_, PyAny>, is_key: bool) -> Result<Ya
735723 let tag_str = tag_obj. downcast :: < PyString > ( ) ?. to_str ( ) ?;
736724 let tag = parse_tag_string ( tag_str) ?;
737725 let inner = py_to_yaml ( py, & value_obj, is_key) ?;
738- return match classify_tag ( & tag) {
739- TagClass :: Canonical ( _) | TagClass :: Core => Ok ( inner) ,
740- TagClass :: NonCore => Ok ( Yaml :: Tagged ( Cow :: Owned ( tag) , Box :: new ( inner) ) ) ,
726+ return if is_core_tag ( & tag) {
727+ Ok ( inner)
728+ } else {
729+ Ok ( Yaml :: Tagged ( Cow :: Owned ( tag) , Box :: new ( inner) ) )
741730 } ;
742731 }
743732
@@ -877,8 +866,8 @@ mod tests {
877866 for input in cases {
878867 let tag = tag_from_scalar ( input) ;
879868 assert_eq ! (
880- canonical_tag_kind ( & tag) ,
881- Some ( CanonicalTagKind :: CoreString ) ,
869+ is_canonical_string_tag ( & tag) ,
870+ true ,
882871 "input `{input}` should map to canonical string tag (handle `{}`, suffix `{}`)" ,
883872 tag. handle,
884873 tag. suffix
@@ -899,8 +888,8 @@ mod tests {
899888 for input in cases {
900889 let tag = tag_from_scalar ( input) ;
901890 assert_eq ! (
902- canonical_tag_kind ( & tag) ,
903- Some ( CanonicalTagKind :: CoreNull ) ,
891+ is_canonical_null_tag ( & tag) ,
892+ true ,
904893 "input `{input}` should map to canonical null tag (handle `{}`, suffix `{}`)" ,
905894 tag. handle,
906895 tag. suffix
0 commit comments