async_snmp/cli/
mib_cli.rs1use crate::mib_support::{self, DiagnosticConfig, Loader, Mib, source};
8use clap::Parser;
9use std::path::PathBuf;
10
11#[derive(Debug, Parser)]
13pub struct MibArgs {
14 #[arg(long = "mib-dir")]
16 pub mib_dir: Vec<PathBuf>,
17
18 #[arg(long = "load-mibs")]
20 pub load_mibs: Vec<String>,
21
22 #[arg(long = "system-mibs")]
24 pub system_mibs: bool,
25}
26
27impl MibArgs {
28 pub fn is_active(&self) -> bool {
30 !self.mib_dir.is_empty() || !self.load_mibs.is_empty() || self.system_mibs
31 }
32
33 pub async fn load(&self) -> Result<Option<Mib>, String> {
39 if !self.is_active() {
40 return Ok(None);
41 }
42
43 let mib_dirs = self.mib_dir.clone();
44 let load_mibs = self.load_mibs.clone();
45 let system_mibs = self.system_mibs;
46
47 let mib =
48 tokio::task::spawn_blocking(move || load_mib_sync(&mib_dirs, &load_mibs, system_mibs))
49 .await
50 .map_err(|e| format!("MIB loading task failed: {}", e))??;
51
52 Ok(Some(mib))
53 }
54}
55
56fn load_mib_sync(
58 mib_dirs: &[PathBuf],
59 load_mibs: &[String],
60 system_mibs: bool,
61) -> Result<Mib, String> {
62 let mut loader = Loader::new();
63
64 for dir in mib_dirs {
66 let source = source::dir(dir)
67 .map_err(|e| format!("failed to open MIB directory {:?}: {}", dir, e))?;
68 loader = loader.source(source);
69 }
70
71 if system_mibs {
73 loader = loader.system_paths();
74 }
75
76 if !load_mibs.is_empty() {
78 loader = loader.modules(load_mibs.iter().map(String::as_str));
79 }
80
81 loader = loader.diagnostic_config(DiagnosticConfig::quiet());
83
84 loader
85 .load()
86 .map_err(|e| format!("MIB loading failed: {}", e))
87}
88
89pub fn resolve_oid_arg(mib: Option<&Mib>, s: &str) -> Result<crate::Oid, String> {
96 if s.chars().next().is_some_and(|c| c.is_ascii_digit()) {
98 return crate::Oid::parse(s).map_err(|e| format!("invalid OID '{}': {}", s, e));
99 }
100
101 if let Some(mib) = mib {
103 return mib_support::resolve_oid(mib, s)
104 .map_err(|e| format!("cannot resolve '{}': {}", s, e));
105 }
106
107 crate::cli::hints::parse_oid(s)
109}