From cb1c0339a845829102bd545db29cbb345c7a1fbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Orhun=20Parmaks=C4=B1z?= Date: Mon, 18 Oct 2021 20:39:45 +0300 Subject: [PATCH] feat(docs): associate the documentation with the parameters --- systeroid-core/src/docs.rs | 2 +- systeroid-core/src/sysctl.rs | 32 +++++++++++++++++++++++++++++++- systeroid/src/lib.rs | 27 +++++++++++++++++++-------- 3 files changed, 51 insertions(+), 10 deletions(-) diff --git a/systeroid-core/src/docs.rs b/systeroid-core/src/docs.rs index 037d62f..4d69a8a 100644 --- a/systeroid-core/src/docs.rs +++ b/systeroid-core/src/docs.rs @@ -2,7 +2,7 @@ use std::fmt::{self, Display, Formatter}; use std::path::{Path, PathBuf}; /// Sections of the sysctl documentation. -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, PartialEq)] pub enum SysctlSection { /// Documentation for `/proc/sys/abi/*` Abi, diff --git a/systeroid-core/src/sysctl.rs b/systeroid-core/src/sysctl.rs index 8d5e076..7fc3d62 100644 --- a/systeroid-core/src/sysctl.rs +++ b/systeroid-core/src/sysctl.rs @@ -1,4 +1,4 @@ -use crate::docs::SysctlSection; +use crate::docs::{Documentation, SysctlSection}; use crate::error::Result; use std::result::Result as StdResult; use sysctl::{CtlIter, Sysctl as SysctlImpl}; @@ -13,6 +13,8 @@ pub struct Parameter { pub description: Option, /// Section of the kernel parameter. pub section: SysctlSection, + /// Documentation of the kernel parameter. + pub documentation: Option, } /// Sysctl wrapper for managing the kernel parameters. @@ -31,8 +33,36 @@ impl Sysctl { value: ctl.value_string()?, description: ctl.description().ok(), section: SysctlSection::from(ctl.name()?), + documentation: None, }); } Ok(Self { parameters }) } + + /// Updates the description of the kernel parameters based on the parsed documentation. + /// + /// [`parsed documentation`]: Documentation + pub fn update_docs(&mut self, docs: Vec) { + for param in self + .parameters + .iter_mut() + .filter(|p| p.description.is_none() || p.description.as_deref() == Some("[N/A]")) + { + if let Some(documentation) = + docs.iter().find( + |doc| match param.name.split('.').collect::>().last() { + Some(absolute_name) => { + absolute_name.len() > 2 + && doc.name.contains(absolute_name) + && doc.section == param.section + } + _ => false, + }, + ) + { + param.description = Some(documentation.description.to_owned()); + param.documentation = Some(documentation.clone()); + } + } + } } diff --git a/systeroid/src/lib.rs b/systeroid/src/lib.rs index 07c60c0..7a4bb43 100644 --- a/systeroid/src/lib.rs +++ b/systeroid/src/lib.rs @@ -17,9 +17,9 @@ use systeroid_parser::parser::RstParser; /// Runs `systeroid`. pub fn run(args: Args) -> Result<()> { - let sysctl = Sysctl::init()?; + let mut sysctl = Sysctl::init()?; - if let Some(kernel_docs) = args.kernel_docs { + let param_docs = if let Some(kernel_docs) = args.kernel_docs { let sysctl_docs = kernel_docs.join("admin-guide").join("sysctl"); if !sysctl_docs.exists() { return Err(IoError::new( @@ -41,18 +41,29 @@ pub fn run(args: Args) -> Result<()> { }; parse(*s) })?; - - let _param_docs = param_docs + let param_docs = param_docs .lock() .map_err(|e| Error::ThreadLockError(e.to_string()))? - .iter() - .collect::>(); + .clone() + .into_iter() + .collect::>(); + Some(param_docs) + } else { + None + }; + + if let Some(param_docs) = param_docs { + sysctl.update_docs(param_docs); } for param in sysctl.parameters { println!( - "{} -> {}: {} ({:?})", - param.section, param.name, param.value, param.description + "{} ({})\n===\n{}\n", + param.name, + param.documentation.map(|d| d.name).unwrap_or_default(), + param + .description + .unwrap_or_else(|| String::from("no documentation")) ); }