Skip to main content

Module tag_registry

Module tag_registry 

Source
Expand description

Streaming-path registry for custom YAML tag pass-through.

The default streaming deserializer routes values carrying a non-core tag (anything outside !!int, !!str, !!bool, …) through the AST fallback so the tag survives as Value::Tagged(...). That’s correct when a caller is reading into Value, but it forces an unnecessary allocation when the caller already knows the tag maps to a concrete Rust type.

TagRegistry lets a caller declare which custom tags should instead be stripped on the streaming path so the inner scalar, sequence, or mapping deserializes directly into the target type — no AST detour, no #[serde(rename = "!…")] dance.

§Examples

use noyalib::{from_str_with_config, ParserConfig, TagRegistry};
use std::sync::Arc;

#[derive(Debug, serde::Deserialize, PartialEq)]
struct Celsius(f64);

let registry = Arc::new(TagRegistry::new().with("!Celsius"));
let cfg = ParserConfig::new().tag_registry(registry);

// Without the registry, `!Celsius 42.5` becomes Value::Tagged and a
// plain `f64` deserialize fails. With the registry, the tag is
// stripped on the streaming path and the scalar deserializes
// directly into the target type.
let c: Celsius = from_str_with_config("!Celsius 42.5", &cfg).unwrap();
assert_eq!(c, Celsius(42.5));

§When you still need #[serde(rename = "!tag")]

The registry strips tags; it does not dispatch. If you’re reading a tagged value into an enum where the tag chooses the variant (!bang → Msg::Bang, !quiet → Msg::Quiet), keep using #[serde(rename)] — serde itself needs the tag string to pick the variant. The registry is for “I already know the type; just get out of my way” newtype/unit-style use cases (the robotics, scientific, and units scenarios in particular).

Structs§

TagRegistry
A set of custom YAML tags that the streaming deserializer should strip and pass through instead of routing via the AST fallback.