Skip to main content

sinter_core/
node.rs

1use serde::{Deserialize, Serialize};
2
3/// Identifier of a graph node.
4///
5/// Comparison is byte-exact and case-sensitive: `Config` and `config` are
6/// distinct ids. A collision on insert is an error, never a merge.
7#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
8pub struct NodeId(String);
9
10impl NodeId {
11    pub fn new(id: impl Into<String>) -> Self {
12        Self(id.into())
13    }
14
15    pub fn as_str(&self) -> &str {
16        &self.0
17    }
18}
19
20impl std::fmt::Display for NodeId {
21    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
22        f.write_str(&self.0)
23    }
24}
25
26/// Byte range of a symbol in its source file. `end` is exclusive; a valid
27/// span has `end > start`.
28#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
29pub struct Span {
30    pub start: u64,
31    pub end: u64,
32}
33
34#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
35pub enum SymbolKind {
36    Function,
37    Method,
38    Struct,
39    Class,
40    Enum,
41    Variant,
42    Trait,
43    Interface,
44    TypeAlias,
45    Constant,
46    Static,
47    Variable,
48    Field,
49    Module,
50    Macro,
51    File,
52    /// A prose document section (markdown heading); appended for postcard
53    /// wire compatibility — never reorder.
54    Section,
55}
56
57impl SymbolKind {
58    pub fn as_str(self) -> &'static str {
59        match self {
60            Self::Function => "function",
61            Self::Method => "method",
62            Self::Struct => "struct",
63            Self::Class => "class",
64            Self::Enum => "enum",
65            Self::Variant => "variant",
66            Self::Trait => "trait",
67            Self::Interface => "interface",
68            Self::TypeAlias => "typealias",
69            Self::Constant => "constant",
70            Self::Static => "static",
71            Self::Variable => "variable",
72            Self::Field => "field",
73            Self::Module => "module",
74            Self::Macro => "macro",
75            Self::File => "file",
76            Self::Section => "section",
77        }
78    }
79
80    /// Inverse of [`SymbolKind::as_str`]; the mapping extraction query
81    /// captures (`@def.<kind>`) resolve through.
82    pub fn from_str_opt(s: &str) -> Option<Self> {
83        Some(match s {
84            "function" => Self::Function,
85            "method" => Self::Method,
86            "struct" => Self::Struct,
87            "class" => Self::Class,
88            "enum" => Self::Enum,
89            "variant" => Self::Variant,
90            "trait" => Self::Trait,
91            "interface" => Self::Interface,
92            "typealias" => Self::TypeAlias,
93            "constant" => Self::Constant,
94            "static" => Self::Static,
95            "variable" => Self::Variable,
96            "field" => Self::Field,
97            "module" => Self::Module,
98            "macro" => Self::Macro,
99            "file" => Self::File,
100            "section" => Self::Section,
101            _ => return None,
102        })
103    }
104}
105
106/// A symbol with enough content that a query result saves the consumer a
107/// file read: signature, doc comment, and exact byte span.
108#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
109pub struct Node {
110    pub id: NodeId,
111    pub kind: SymbolKind,
112    pub name: String,
113    /// Repo-relative source file path.
114    pub file: String,
115    pub span: Span,
116    /// Declaration text; may be empty for kinds with no meaningful signature.
117    pub signature: String,
118    pub doc: Option<String>,
119}