Skip to main content

big_code_analysis_ast/
space_kind.rs

1//! The kinds of space the walk opens: functions and the containers
2//! (class, struct, trait, impl, namespace, interface) plus the file unit.
3//!
4//! Defined beside the classifiers because `Getter::get_space_kind`
5//! returns it; `spaces` re-exports it under its historical public path
6//! (#1376).
7
8use std::fmt;
9
10use serde::{Deserialize, Serialize};
11
12/// The list of supported space kinds.
13// New space kinds land as languages are added (a future module-, mixin-,
14// or enum-style space), so this is marked `#[non_exhaustive]` to keep
15// such additions additive rather than a 2.0 break. CLI/web consumers
16// matching on it already carry a `_ =>` arm.
17#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
18#[serde(rename_all = "lowercase")]
19#[non_exhaustive]
20pub enum SpaceKind {
21    /// An unknown space
22    #[default]
23    Unknown,
24    /// A function space
25    Function,
26    /// A class space
27    Class,
28    /// A struct space
29    Struct,
30    /// A `Rust` trait space
31    Trait,
32    /// A `Rust` implementation space
33    Impl,
34    /// A general space
35    Unit,
36    /// A `C/C++` namespace
37    Namespace,
38    /// An interface
39    Interface,
40}
41
42impl SpaceKind {
43    /// Parse a [`SpaceKind`] from its lowercase serialized form — the
44    /// `#[serde(rename_all = "lowercase")]` representation that appears in
45    /// the JSON / wire `kind` field. An unrecognized string maps to
46    /// [`SpaceKind::Unknown`] so a JSON-walking front-end degrades
47    /// gracefully on a future kind rather than erroring.
48    ///
49    /// This is the single source of truth for the string-to-kind mapping a
50    /// consumer needs when it reads a serialized `kind` (the Python
51    /// `to_sarif` binding uses it to apply per-metric threshold scope via
52    /// `metric_catalog::MetricScope::admits`). A round-trip test
53    /// pins it against the serde representation so the two cannot drift.
54    #[must_use]
55    pub fn from_serialized(serialized: &str) -> Self {
56        match serialized {
57            "function" => Self::Function,
58            "class" => Self::Class,
59            "struct" => Self::Struct,
60            "trait" => Self::Trait,
61            "impl" => Self::Impl,
62            "unit" => Self::Unit,
63            "namespace" => Self::Namespace,
64            "interface" => Self::Interface,
65            _ => Self::Unknown,
66        }
67    }
68}
69
70impl fmt::Display for SpaceKind {
71    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
72        let s = match self {
73            SpaceKind::Unknown => "unknown",
74            SpaceKind::Function => "function",
75            SpaceKind::Class => "class",
76            SpaceKind::Struct => "struct",
77            SpaceKind::Trait => "trait",
78            SpaceKind::Impl => "impl",
79            SpaceKind::Unit => "unit",
80            SpaceKind::Namespace => "namespace",
81            SpaceKind::Interface => "interface",
82        };
83        write!(f, "{s}")
84    }
85}