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)
| 230 | /// dependency chain, so edges like `verifiedBy`/`about` are rejected even though |
| 231 | /// they are valid edges elsewhere. |
| 232 | fn lift_ref(d: &Directive) -> Result<Ref> { |
| 233 | let to = d |
| 234 | .attr("to") |
| 235 | .ok_or_else(|| CanonicalError::Lift("':::ref' is missing required 'to'".into()))? |
| 236 | .to_string(); |
| 237 | let edge = d |
| 238 | .attr("edge") |
| 239 | .ok_or_else(|| CanonicalError::Lift("':::ref' is missing required 'edge'".into()))? |
| 240 | .to_string(); |
| 241 | if !vocab::is_known_dependency_edge(&edge) { |
| 242 | return Err(CanonicalError::Lift(format!( |
| 243 | "':::ref' edge '{edge}' is not a dependency edge {:?}", |
| 244 | vocab::DEPENDENCY_EDGES |
| 245 | ))); |
| 246 | } |
| 247 | Ok(Ref { |
| 248 | type_: d.id.as_ref().map(|_| NodeType::Ref.as_str().to_string()), |
| 249 | id: d.id.as_ref().map(|id| as_urn("ref", id)), |
| 250 | to, |
| 251 | edge, |
| 252 | }) |
| 253 | } |
| 254 | |
| 255 | /// Wrap a local id into `urn:atomic:<kind>:<local>` unless already a urn. |
| 256 | fn as_urn(kind: &str, local: &str) -> String { |
no test coverage detected