pub type IncludeResolver<'a> = dyn FnMut(IncludeRequest<'_>) -> Result<ResolvedInclude, IncludeResolveError> + 'a;Expand description
Callback used to resolve !include directives during parsing.
The resolver receives an IncludeRequest describing what was requested, from which
source it originated, and where in the source file the directive was encountered. It must
either return a ResolvedInclude with a stable id, human-friendly name, and the
replacement InputSource, or fail with IncludeResolveError.
The id should uniquely identify the underlying resource after any normalization you need
(for example, a canonical filesystem path or a normalized URL). serde-saphyr uses this
identifier for include-stack tracking and cycle detection. The name is intended for error
messages and can be more user-friendly.
Resolvers may return:
InputSource::Textfor ordinary in-memory YAML,InputSource::AnchoredTextwhen the include should behave as if a specific anchor was the first parsed node, orInputSource::Readerwhen content should be streamed from an owned reader.
A resolver is invoked lazily, when a !include tag is encountered. Because the type is
FnMut, the callback may keep state such as caches, metrics, or a virtual file map.
use serde::Deserialize;
use serde_saphyr::{
from_str_with_options, options, IncludeRequest, IncludeResolveError, InputSource,
ResolvedInclude,
};
#[derive(Debug, Deserialize, PartialEq)]
struct Config {
users: Vec<User>,
}
#[derive(Debug, Deserialize, PartialEq)]
struct User {
name: String,
}
let root_yaml = "users: !include virtual://users.yaml\n";
let users_yaml = "- name: Alice\n- name: Bob\n";
let options = options! {}.with_include_resolver(|req: IncludeRequest<'_>| {
assert_eq!(req.spec, "virtual://users.yaml");
assert_eq!(req.from_name, "<input>");
if req.spec == "virtual://users.yaml" {
Ok(ResolvedInclude {
id: req.spec.to_owned(),
name: "virtual users".to_owned(),
source: InputSource::from_string(users_yaml.to_owned()),
})
} else {
Err(IncludeResolveError::Message(format!("unknown include: {}", req.spec)))
}
});
let config: Config = from_str_with_options(root_yaml, options).unwrap();
assert_eq!(config.users.len(), 2);
assert_eq!(config.users[0].name, "Alice");