Skip to main content

IncludeResolver

Type Alias IncludeResolver 

Source
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:

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");