use crate::mib_support::{self, DiagnosticConfig, Loader, Mib, source};
use clap::Parser;
use std::path::PathBuf;
#[derive(Debug, Parser)]
pub struct MibArgs {
#[arg(long = "mib-dir")]
pub mib_dir: Vec<PathBuf>,
#[arg(long = "load-mibs")]
pub load_mibs: Vec<String>,
#[arg(long = "system-mibs")]
pub system_mibs: bool,
}
impl MibArgs {
pub fn is_active(&self) -> bool {
!self.mib_dir.is_empty() || !self.load_mibs.is_empty() || self.system_mibs
}
pub async fn load(&self) -> Result<Option<Mib>, String> {
if !self.is_active() {
return Ok(None);
}
let mib_dirs = self.mib_dir.clone();
let load_mibs = self.load_mibs.clone();
let system_mibs = self.system_mibs;
let mib =
tokio::task::spawn_blocking(move || load_mib_sync(&mib_dirs, &load_mibs, system_mibs))
.await
.map_err(|e| format!("MIB loading task failed: {}", e))??;
Ok(Some(mib))
}
}
fn load_mib_sync(
mib_dirs: &[PathBuf],
load_mibs: &[String],
system_mibs: bool,
) -> Result<Mib, String> {
let mut loader = Loader::new();
for dir in mib_dirs {
let source = source::dir(dir)
.map_err(|e| format!("failed to open MIB directory {:?}: {}", dir, e))?;
loader = loader.source(source);
}
if system_mibs {
loader = loader.system_paths();
}
if !load_mibs.is_empty() {
loader = loader.modules(load_mibs.iter().map(String::as_str));
}
loader = loader.diagnostic_config(DiagnosticConfig::quiet());
loader
.load()
.map_err(|e| format!("MIB loading failed: {}", e))
}
pub fn resolve_oid_arg(mib: Option<&Mib>, s: &str) -> Result<crate::Oid, String> {
if s.chars().next().is_some_and(|c| c.is_ascii_digit()) {
return crate::Oid::parse(s).map_err(|e| format!("invalid OID '{}': {}", s, e));
}
if let Some(mib) = mib {
return mib_support::resolve_oid(mib, s)
.map_err(|e| format!("cannot resolve '{}': {}", s, e));
}
crate::cli::hints::parse_oid(s)
}