Skip to content

Commit ad1117c

Browse files
committed
Simplify core tag handling and drop TagClass plumbing
1 parent 2caad38 commit ad1117c

File tree

1 file changed

+62
-73
lines changed

1 file changed

+62
-73
lines changed

src/lib.rs

Lines changed: 62 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,6 @@ type Result<T> = PyResult<T>;
2020

2121
static 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)]
3624
struct 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

638626
fn 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

Comments
 (0)