use mib_rs::{BaseType, Loader};
fn main() {
let source = mib_rs::source::memory(
"EXAMPLE-FULL-MIB",
include_bytes!("../tests/data/example-full-mib.txt").as_slice(),
);
let mib = Loader::new()
.source(source)
.modules(["EXAMPLE-FULL-MIB"])
.load()
.expect("should load");
let ty = mib.r#type("ExPercentage").unwrap();
println!("=== ExPercentage ===");
println!(" Name: {}", ty.name());
println!(" Is TC: {}", ty.is_textual_convention());
println!(" Base: {:?}", ty.base());
println!(" Eff. base: {:?}", ty.effective_base());
println!(" Display hint: {:?}", ty.display_hint());
println!(" Eff. hint: {:?}", ty.effective_display_hint());
println!(" Status: {:?}", ty.status());
println!(" Description: {}", ty.description());
assert_eq!(ty.effective_base(), BaseType::Integer32);
assert_eq!(ty.effective_display_hint(), "d-%");
let ranges = ty.effective_ranges();
println!(" Ranges:");
for r in ranges {
println!(" {}..{}", r.min, r.max);
}
let ty = mib.r#type("ExName").unwrap();
println!("\n=== ExName ===");
println!(" Eff. base: {:?}", ty.effective_base());
println!(" Display hint: {:?}", ty.effective_display_hint());
let sizes = ty.effective_sizes();
println!(" Sizes:");
for s in sizes {
println!(" {}..{}", s.min, s.max);
}
assert!(ty.is_string());
let ty = mib.r#type("ExDeviceStatus").unwrap();
println!("\n=== ExDeviceStatus ===");
println!(" Is TC: {}", ty.is_textual_convention());
println!(" Is enum: {}", ty.is_enumeration());
println!(" Eff. base: {:?}", ty.effective_base());
let enums = ty.effective_enums();
println!(" Enum values:");
for e in enums {
println!(" {}({})", e.label, e.value);
}
let ty = mib.r#type("ExName").unwrap();
println!("\n=== Type chain: ExName ===");
print_type_chain(&ty);
let ty = mib.r#type("ExPercentage").unwrap();
println!("\n=== Type chain: ExPercentage ===");
print_type_chain(&ty);
let obj = mib.object("exIfSpeed").unwrap();
let ty = obj.ty().unwrap();
println!("\n=== exIfSpeed type ===");
println!(" Type name: {}", ty.name());
println!(" Is gauge: {}", ty.is_gauge());
println!(" Eff. base: {:?}", ty.effective_base());
assert!(ty.is_gauge());
let obj = mib.object("exUptime").unwrap();
let ty = obj.ty().unwrap();
println!("\n=== exUptime type ===");
println!(" Type name: {}", ty.name());
println!(" Is counter: {}", ty.is_counter());
assert!(ty.is_counter());
let obj = mib.object("exDeviceName").unwrap();
println!("\n=== Object effective accessors ===");
println!(
" exDeviceName.effective_display_hint: {:?}",
obj.effective_display_hint()
);
println!(
" exDeviceName.effective_sizes: {:?}",
obj.effective_sizes()
);
let obj = mib.object("exDeviceStatus").unwrap();
println!(" exDeviceStatus.effective_enums:");
for e in obj.effective_enums() {
println!(" {}({})", e.label, e.value);
}
use mib_rs::mib::display_hint::{self, HexCase};
let obj = mib.object("exTemperature").unwrap();
println!("\n=== Display-hint formatting ===");
println!(" hint: {:?}", obj.effective_display_hint());
println!(
" format(2345): {:?}",
obj.format_integer(2345, HexCase::Upper)
);
println!(" scale(2345): {:?}", obj.scale_integer(2345));
println!(" units: {:?}", obj.units());
assert_eq!(
obj.format_integer(2345, HexCase::Upper),
Some("23.45".into())
);
assert_eq!(obj.scale_integer(2345), Some(23.45));
let obj = mib.object("exDeviceMac").unwrap();
let mac = [0x00, 0x1a, 0x2b, 0x3c, 0x4d, 0x5e];
println!(
" mac format: {:?}",
obj.format_octets(&mac, HexCase::Upper)
);
assert_eq!(
obj.format_octets(&mac, HexCase::Upper),
Some("00:1A:2B:3C:4D:5E".into())
);
let obj = mib.object("exDeviceName").unwrap();
println!(
" name format: {:?}",
obj.format_octets(b"switch-01", HexCase::Upper)
);
assert_eq!(
obj.format_octets(b"switch-01", HexCase::Upper),
Some("switch-01".into()),
);
let obj = mib.object("exUptime").unwrap();
assert_eq!(obj.format_integer(12345, HexCase::Upper), None);
assert_eq!(
display_hint::format_integer("d-2", 1234, HexCase::Upper),
Some("12.34".into())
);
assert_eq!(
display_hint::format_octets("1d.1d.1d.1d", &[10, 0, 0, 1], HexCase::Upper),
Some("10.0.0.1".into())
);
let obj = mib.object("exUptime").unwrap();
println!("\n exUptime.units: {:?}", obj.units());
let obj = mib.object("exIfSpeed").unwrap();
println!(" exIfSpeed.units: {:?}", obj.units());
let obj = mib.object("exRebootEnabled").unwrap();
if let Some(defval) = obj.default_value() {
println!(
"\n exRebootEnabled.defval: {} (kind={:?})",
defval,
defval.kind()
);
}
println!("\n=== Type classification ===");
for name in ["ExName", "ExPercentage", "ExDeviceStatus"] {
let ty = mib.r#type(name).unwrap();
println!(
" {:<20} string={:<5} counter={:<5} gauge={:<5} enum={:<5} bits={:<5}",
ty.name(),
ty.is_string(),
ty.is_counter(),
ty.is_gauge(),
ty.is_enumeration(),
ty.is_bits(),
);
}
println!("\n=== All user-defined types ===");
let module = mib.module("EXAMPLE-FULL-MIB").unwrap();
for ty in module.types() {
let parent_name = ty
.parent()
.map(|p| p.name().to_string())
.unwrap_or_default();
println!(
" {:<20} base={:<16?} parent={:<20} tc={}",
ty.name(),
ty.effective_base(),
parent_name,
ty.is_textual_convention(),
);
}
}
fn print_type_chain(ty: &mib_rs::Type<'_>) {
let mut current = Some(*ty);
let mut depth = 0;
while let Some(t) = current {
let indent = " ".repeat(depth + 1);
let hint = t.display_hint();
let hint_str = if hint.is_empty() {
String::new()
} else {
format!(" hint={hint:?}")
};
println!(
"{}{} (base={:?}, tc={}{})",
indent,
t.name(),
t.base(),
t.is_textual_convention(),
hint_str,
);
current = t.parent();
depth += 1;
}
}