Lift a `:::ref{to= edge=}` leaf into a typed reference edge. Both `to` and `edge` are required (a ref with no target or no edge type is a lift error), and `edge` must be a known *ref* edge: a dependency edge (`depends`/ `blockedBy`) or a remediation edge (`remediates`). Edges like `verifiedBy`/`about` are rejected even though they are valid edges elsewhere.
(d: &Directive)
| 285 | /// `blockedBy`) or a remediation edge (`remediates`). Edges like |
| 286 | /// `verifiedBy`/`about` are rejected even though they are valid edges elsewhere. |
| 287 | fn lift_ref(d: &Directive) -> Result<Ref> { |
| 288 | let to = d |
| 289 | .attr("to") |
| 290 | .ok_or_else(|| CanonicalError::Lift("':::ref' is missing required 'to'".into()))? |
| 291 | .to_string(); |
| 292 | let edge = d |
| 293 | .attr("edge") |
| 294 | .ok_or_else(|| CanonicalError::Lift("':::ref' is missing required 'edge'".into()))? |
| 295 | .to_string(); |
| 296 | if !vocab::is_known_ref_edge(&edge) { |
| 297 | return Err(CanonicalError::Lift(format!( |
| 298 | "':::ref' edge '{edge}' is not a valid ref edge (dependency {:?} or remediation {:?})", |
| 299 | vocab::DEPENDENCY_EDGES, |
| 300 | vocab::REMEDIATION_EDGES |
| 301 | ))); |
| 302 | } |
| 303 | Ok(Ref { |
| 304 | type_: d.id.as_ref().map(|_| NodeType::Ref.as_str().to_string()), |
| 305 | id: d.id.as_ref().map(|id| as_urn("ref", id)), |
| 306 | to, |
| 307 | edge, |
| 308 | }) |
| 309 | } |
| 310 | |
| 311 | /// Wrap a local id into `urn:atomic:<kind>:<local>` unless already a urn. |
| 312 | fn as_urn(kind: &str, local: &str) -> String { |
no test coverage detected