Skip to main content

nodex_core/model/
edge.rs

1use serde::{Deserialize, Serialize};
2
3use super::confidence::Confidence;
4
5/// A resolved edge in the graph.
6#[derive(Debug, Clone, Serialize, Deserialize)]
7pub struct Edge {
8    pub source: String,
9    pub target: ResolvedTarget,
10    pub relation: String,
11    pub confidence: Confidence,
12    /// Source location, e.g. "L42" or "frontmatter:supersedes".
13    pub location: String,
14}
15
16/// Type-safe representation of an edge target.
17#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
18#[serde(tag = "type", rename_all = "snake_case")]
19pub enum ResolvedTarget {
20    /// Successfully resolved to a node id.
21    Resolved { id: String },
22    /// Could not be resolved — external or missing reference.
23    Unresolved { raw: String, reason: String },
24}
25
26impl ResolvedTarget {
27    pub fn resolved(id: impl Into<String>) -> Self {
28        Self::Resolved { id: id.into() }
29    }
30
31    pub fn unresolved(raw: impl Into<String>, reason: impl Into<String>) -> Self {
32        Self::Unresolved {
33            raw: raw.into(),
34            reason: reason.into(),
35        }
36    }
37
38    /// Returns the resolved node id, or `None` if unresolved.
39    pub fn id(&self) -> Option<&str> {
40        match self {
41            Self::Resolved { id } => Some(id),
42            Self::Unresolved { .. } => None,
43        }
44    }
45}
46
47/// An edge before target resolution (produced by the parser).
48#[derive(Debug, Clone)]
49pub struct RawEdge {
50    /// Raw target path or id from the document.
51    pub target_path: String,
52    pub relation: String,
53    pub confidence: Confidence,
54    /// Source location, e.g. "L42" or "frontmatter:supersedes".
55    pub location: String,
56}