Lift a `:::ref{to= edge=}` leaf into a typed dependency edge. Both `to` and `edge` are required (a dependency with no target or no edge type is a lift error), and `edge` must be a known *dependency* edge — a `:::ref` sits on the dependency chain, so edges like `verifiedBy`/`about` are rejected even though they are valid edges elsewhere.
(d: &Directive)
| 213 | /// dependency chain, so edges like `verifiedBy`/`about` are rejected even though |
| 214 | /// they are valid edges elsewhere. |
| 215 | fn lift_ref(d: &Directive) -> Result<Ref> { |
| 216 | let to = d |
| 217 | .attr("to") |
| 218 | .ok_or_else(|| CanonicalError::Lift("':::ref' is missing required 'to'".into()))? |
| 219 | .to_string(); |
| 220 | let edge = d |
| 221 | .attr("edge") |
| 222 | .ok_or_else(|| CanonicalError::Lift("':::ref' is missing required 'edge'".into()))? |
| 223 | .to_string(); |
| 224 | if !vocab::is_known_dependency_edge(&edge) { |
| 225 | return Err(CanonicalError::Lift(format!( |
| 226 | "':::ref' edge '{edge}' is not a dependency edge {:?}", |
| 227 | vocab::DEPENDENCY_EDGES |
| 228 | ))); |
| 229 | } |
| 230 | Ok(Ref { |
| 231 | type_: d.id.as_ref().map(|_| NodeType::Ref.as_str().to_string()), |
| 232 | id: d.id.as_ref().map(|id| as_urn("ref", id)), |
| 233 | to, |
| 234 | edge, |
| 235 | }) |
| 236 | } |
| 237 | |
| 238 | /// Wrap a local id into `urn:atomic:<kind>:<local>` unless already a urn. |
| 239 | fn as_urn(kind: &str, local: &str) -> String { |
no test coverage detected