use crate::Provenance;
use crate::model::{Node, NodeKind};
pub const LINKS_REF: &str = "import:links";
pub const EXTERNAL_REF_KIND: &str = "external_ref";
#[must_use]
pub fn external_ref_node(qualified: &str) -> Node {
let mut node = Node::new(
external_ref_key(qualified),
NodeKind::Other(EXTERNAL_REF_KIND.to_owned()),
qualified.to_owned(),
)
.with_provenance(Provenance::Inferred);
node.meta = serde_json::json!({ "qualified": qualified });
node
}
#[must_use]
pub fn external_ref_key(qualified: &str) -> String {
format!("extref:{qualified}")
}
#[must_use]
pub fn external_ref_target(node: &Node) -> Option<String> {
if node.kind.as_str() != EXTERNAL_REF_KIND {
return None;
}
node.meta
.get("qualified")
.and_then(serde_json::Value::as_str)
.map(str::to_owned)
.or_else(|| node.key.strip_prefix("extref:").map(str::to_owned))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn external_ref_round_trips_its_qualified_target() {
let q = "app::cfgkey:config.toml#serve.addr";
let node = external_ref_node(q);
assert_eq!(node.key, "extref:app::cfgkey:config.toml#serve.addr");
assert_eq!(node.kind, NodeKind::Other("external_ref".to_owned()));
assert_eq!(node.provenance, Provenance::Inferred);
assert_eq!(external_ref_target(&node).as_deref(), Some(q));
}
#[test]
fn target_falls_back_to_the_key_prefix_when_meta_is_missing() {
let mut node = external_ref_node("app::file:x");
node.meta = serde_json::Value::Null;
assert_eq!(external_ref_target(&node).as_deref(), Some("app::file:x"));
}
#[test]
fn non_external_ref_has_no_target() {
let node = Node::new("file:x", NodeKind::File, "x");
assert_eq!(external_ref_target(&node), None);
}
}