Skip to main content

mib_rs/ir/
mod.rs

1//! Intermediate representation produced by [lowering](crate::lower) the AST.
2//!
3//! The IR is language-independent: SMIv1 and SMIv2 constructs are unified
4//! (e.g. `TRAP-TYPE` and `NOTIFICATION-TYPE` both become [`Notification`]).
5//! Type and OID references remain unresolved strings until the resolver phase
6//! transforms the IR into a fully resolved [`Mib`](crate::mib::Mib).
7//!
8//! Unlike the AST, the IR generally uses plain `String` values instead of
9//! [`Ident`](crate::ast::Ident) nodes. References that need precise diagnostics
10//! use [`NameRef`], and optional clauses are represented as empty strings rather
11//! than `Option`s.
12
13pub mod definition;
14pub mod oid;
15pub mod syntax;
16
17pub use definition::*;
18pub use oid::{OidAssignment, OidComponent};
19pub use syntax::*;
20
21use crate::source::{SourceId, SourceRange};
22use crate::types::{Diagnostic, Language};
23
24/// A normalized, language-independent MIB module.
25///
26/// Lowering transforms AST structures into this simplified representation
27/// independent of whether the source was SMIv1 or SMIv2.
28#[derive(Debug, Clone)]
29pub struct Module {
30    /// Canonical module name (e.g. `"IF-MIB"`).
31    pub name: String,
32    /// Detected SMI language version, or [`Language::Unknown`] when syntax and
33    /// imports provide insufficient or conflicting version evidence.
34    pub language: Language,
35    /// Flattened imports: one [`Import`] per imported symbol.
36    pub imports: Vec<Import>,
37    /// All definitions in source order.
38    pub definitions: Vec<Definition>,
39    /// Range covering the entire module, or `None` for a generated module.
40    pub range: Option<SourceRange>,
41    /// Diagnostics collected during lowering.
42    pub diagnostics: Vec<Diagnostic>,
43    /// Compilation-local source document containing this module.
44    pub(crate) source_id: Option<SourceId>,
45}
46
47impl Module {
48    /// Creates a new module with the given name and source range. All other fields
49    /// are initialized to empty/default values.
50    pub fn new(name: String, range: Option<SourceRange>) -> Self {
51        let source_id = range.map(SourceRange::source);
52        Module {
53            name,
54            language: Language::Unknown,
55            imports: Vec::new(),
56            definitions: Vec::new(),
57            range,
58            diagnostics: Vec::new(),
59            source_id,
60        }
61    }
62
63    /// Returns an iterator over the names of all definitions.
64    pub fn definition_names(&self) -> impl Iterator<Item = &str> {
65        self.definitions.iter().map(|d| d.name())
66    }
67}
68
69/// A single imported symbol, flattened from the AST's grouped format.
70#[derive(Debug, Clone)]
71pub struct Import {
72    /// Source module name (the FROM target).
73    pub module: String,
74    /// Imported symbol name.
75    pub symbol: String,
76    /// Source range of the symbol in the `IMPORTS` section.
77    pub range: SourceRange,
78}