about summary refs log tree commit diff
diff options
context:
space:
mode:
authorProfpatsch <mail@profpatsch.de>2024-03-04 00:11:33 +0100
committerProfpatsch <mail@profpatsch.de>2024-03-04 00:13:11 +0100
commit5501922264e4b2ac2bcfc8ec28a248df0fa749f8 (patch)
tree4e0b91c1e476b2d3a71a03508d6f3eff83d0f287
parent257b6144fa27c030a8eee45b8c832c769b9a1ffd (diff)
pkgs/profpatsch/nman: really enumerate (all) manpages
We enumerate every single manpage, then we only take the first manpage
that is in our section or just the first manpage that is named
correctly.
-rw-r--r--pkgs/profpatsch/nman/nman.rs68
1 files changed, 39 insertions, 29 deletions
diff --git a/pkgs/profpatsch/nman/nman.rs b/pkgs/profpatsch/nman/nman.rs
index b9961f1e..7c43260a 100644
--- a/pkgs/profpatsch/nman/nman.rs
+++ b/pkgs/profpatsch/nman/nman.rs
@@ -273,8 +273,18 @@ enum OutputDirResult {
     FoundManPage(PathBuf),
 }
 
-struct FoundManSection {
+struct FoundManPage {
     man_section: String,
+    file_name: String,
+}
+
+impl FoundManPage {
+    /// From a share/man path we can reconstruct the full manpage path.
+    fn manpage_path(&self, share_man: PathBuf) -> PathBuf {
+        return share_man
+            .join(String::from("man") + &self.man_section)
+            .join(&self.file_name);
+    }
 }
 
 impl Main {
@@ -413,57 +423,57 @@ impl Main {
 
         // expected sub directory of share/man or, if no section
         // is given, all potential sub directories
-        let mut section_dirs: Vec<FoundManSection> = Self::enumerate_man_pages(&drv_share_man)?;
-        if let Some(sect) = section {
-            section_dirs = section_dirs
-                .into_iter()
-                .find(|man| man.man_section == sect)
-                .map_or(Vec::new(), |x| vec![x]);
-        }
+        let mut manpages: Vec<FoundManPage> = Self::enumerate_man_pages(&drv_share_man)?;
 
         // sorting should be ascending in terms of numerics,
         // apart from that, not many requirements
-        section_dirs.sort_unstable_by(|man1, man2| man1.man_section.cmp(&man2.man_section));
-
-        for ref section_dir in section_dirs {
-            // we have a valid man dir, check if it contains our page section
-            let section_path = drv_share_man.join(String::from("man") + &section_dir.man_section);
-            let dir_content = read_dir(section_path).map_err(NmanError::IO)?;
+        manpages.sort_unstable_by(|man1, man2| man1.man_section.cmp(&man2.man_section));
 
-            for entry in dir_content {
-                let file = entry.map_err(NmanError::IO)?;
-                let mmatch = file
-                    .file_name()
-                    .to_str()
-                    .map(|f| match_man_page_file(f, &section_dir.man_section, page));
-
-                if mmatch.unwrap_or(false) {
-                    return Ok(OutputDirResult::FoundManPage(file.path()));
+        // take the first manpage that matches our criteria
+        for ref manpage in manpages {
+            // If we want to restrict to a section, skip manpages of the wrong section.
+            if let Some(sect) = section {
+                if sect != manpage.man_section {
+                    continue;
                 }
             }
+            if match_man_page_file(&manpage.file_name, &manpage.man_section, page) {
+                return Ok(OutputDirResult::FoundManPage(
+                    manpage.manpage_path(drv_share_man),
+                ));
+            }
         }
 
         Ok(OutputDirResult::NoManPageFound)
     }
 
-    fn enumerate_man_pages<'a>(path: &PathBuf) -> Result<Vec<FoundManSection>, NmanError<'a>> {
+    fn enumerate_man_pages<'a>(path: &PathBuf) -> Result<Vec<FoundManPage>, NmanError<'a>> {
         let dirs = read_dir(path.as_path()).map_err(NmanError::IO)?;
         let mut res = Vec::new();
         for entry in dirs.collect::<Vec<_>>() {
             // ignore directories/files that cannot be read
-            if let Ok(e) = entry {
+            if let Ok(section_dir) = entry {
                 // separate "man" prefix from section indicator,
                 // while validating the particular sub directory
-                if let Some((prefix, man_section)) = e
+                if let Some((prefix, man_section)) = section_dir
                     .file_name()
                     .to_str()
                     .filter(|d| d.len() > 3)
                     .map(|d| d.split_at(3))
                 {
                     if prefix == "man" {
-                        res.push(FoundManSection {
-                            man_section: String::from(man_section),
-                        })
+                        let manpages = read_dir(section_dir.path()).map_err(NmanError::IO)?;
+                        for manpage in manpages.collect::<Vec<_>>() {
+                            // ignore directories/files that cannot be read
+                            if let Ok(Some(file_name)) =
+                                manpage.map(|mp| mp.file_name().to_str().map(String::from))
+                            {
+                                res.push(FoundManPage {
+                                    man_section: String::from(man_section),
+                                    file_name,
+                                })
+                            }
+                        }
                     }
                 }
             }