Skip to main content

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}