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 uses plain `String` values instead of [`Ident`](crate::ast::Ident)
9//! nodes, and optional clauses are represented as empty strings rather than `Option`s.
10
11pub mod definition;
12pub mod oid;
13pub mod syntax;
14
15pub use definition::*;
16pub use oid::{OidAssignment, OidComponent};
17pub use syntax::*;
18
19use crate::types::{Diagnostic, Language, Span};
20
21/// A normalized, language-independent MIB module.
22///
23/// Lowering transforms AST structures into this simplified representation
24/// independent of whether the source was SMIv1 or SMIv2.
25#[derive(Debug, Clone)]
26pub struct Module {
27    /// Canonical module name (e.g. `"IF-MIB"`).
28    pub name: String,
29    /// Detected SMI language version.
30    pub language: Language,
31    /// Flattened imports: one [`Import`] per imported symbol.
32    pub imports: Vec<Import>,
33    /// All definitions in source order.
34    pub definitions: Vec<Definition>,
35    /// Span covering the entire module.
36    pub span: Span,
37    /// Diagnostics collected during lowering.
38    pub diagnostics: Vec<Diagnostic>,
39    /// File path this module was loaded from. Empty for synthetic base modules.
40    pub source_path: String,
41    /// Maps line numbers to byte offsets of line starts.
42    /// Entry i holds the byte offset where line i+1 begins (0-indexed).
43    pub line_table: Vec<usize>,
44}
45
46impl Module {
47    /// Creates a new module with the given name and span. All other fields
48    /// are initialized to empty/default values.
49    pub fn new(name: String, span: Span) -> Self {
50        Module {
51            name,
52            language: Language::Unknown,
53            imports: Vec::new(),
54            definitions: Vec::new(),
55            span,
56            diagnostics: Vec::new(),
57            source_path: String::new(),
58            line_table: Vec::new(),
59        }
60    }
61
62    /// Returns an iterator over the names of all definitions.
63    pub fn definition_names(&self) -> impl Iterator<Item = &str> {
64        self.definitions.iter().map(|d| d.name())
65    }
66}
67
68/// A single imported symbol, flattened from the AST's grouped format.
69#[derive(Debug, Clone)]
70pub struct Import {
71    /// Source module name (the FROM target).
72    pub module: String,
73    /// Imported symbol name.
74    pub symbol: String,
75    /// Source span of the symbol in the `IMPORTS` section.
76    pub span: Span,
77}