reference_query/core/symbol.rs
1//! The common symbol model every language plugin emits.
2
3use std::fmt;
4
5/// The kind of definition a [`Symbol`] represents.
6///
7/// A small, *language-agnostic* vocabulary of definition kinds — the shared
8/// model every plugin maps onto, deliberately generalized rather than per
9/// language (Rust's `struct`/`enum`/`trait` sit beside Ruby's `class`/`module`).
10/// It covers *definitions only*: call graphs, references, and inheritance are
11/// explicit non-goals (see `docs/ROADMAP.md`). Add a variant when a language
12/// needs a kind the model can't yet express, not a language-specific one-off.
13#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
14pub enum Kind {
15 Class,
16 Module,
17 Method,
18 Function,
19 Struct,
20 Enum,
21 Trait,
22}
23
24impl Kind {
25 /// Stable lowercase tag used in storage and output.
26 pub fn as_str(self) -> &'static str {
27 match self {
28 Kind::Class => "class",
29 Kind::Module => "module",
30 Kind::Method => "method",
31 Kind::Function => "function",
32 Kind::Struct => "struct",
33 Kind::Enum => "enum",
34 Kind::Trait => "trait",
35 }
36 }
37}
38
39impl fmt::Display for Kind {
40 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41 f.write_str(self.as_str())
42 }
43}
44
45/// A definition extracted from source.
46///
47/// Every language plugin emits this same shape; the core never sees a
48/// language-specific concept. `parent` records *lexical* nesting only
49/// (e.g. `Foo::Bar#baz`) — it is not reference tracking or inheritance.
50#[derive(Debug, Clone, PartialEq, Eq)]
51pub struct Symbol {
52 /// The defined name, e.g. `RefundProcessor`, `perform`.
53 pub name: String,
54 pub kind: Kind,
55 /// Language tag, e.g. `ruby`.
56 pub language: String,
57 /// Repository-relative path.
58 pub file: String,
59 /// 1-based line of the definition.
60 pub line: u32,
61 /// 1-based last line of the definition's body — with `line`, the span to
62 /// read to see the whole definition. Equals `line` for a one-line symbol.
63 pub end_line: u32,
64 /// Enclosing symbol name, if any (lexical nesting only).
65 pub parent: Option<String>,
66 /// Access level when the language expresses one: `public`, `crate`,
67 /// `private`, or `protected`. `None` when unknown. A ranking hint (private
68 /// helpers sit below public API), never a filter.
69 pub visibility: Option<&'static str>,
70}
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75
76 #[test]
77 fn kind_tag_is_stable_and_lowercase() {
78 assert_eq!(Kind::Class.as_str(), "class");
79 assert_eq!(Kind::Module.to_string(), "module");
80 assert_eq!(Kind::Method.as_str(), "method");
81 assert_eq!(Kind::Function.as_str(), "function");
82 assert_eq!(Kind::Struct.as_str(), "struct");
83 assert_eq!(Kind::Enum.as_str(), "enum");
84 assert_eq!(Kind::Trait.as_str(), "trait");
85 }
86}