Repository: igumnoff/shiva (language: rust)

Issue:
Allow standard markdown extension in `bin`, ie `.md` as well as `.markdown`
At the moment the _`shiva` binary_ complains if I try e.g. 

```
shiva sample.md sample.pdf
```

and instead requires renaming to `.markdown`. As `.md` is one of the standard markdown file extensions (possibly more common than `.markdown`?), this is seems illogical.


Discussion / hints:
yeap. we need add alias "md" for "markdown"

are you ready to do it?
No sorry, I don't know this crate well enough and don't have availability right now. If this doesn't get resolved and I find the time I'll let you know.

Fix patch:
diff --git a/cli/src/main.rs b/cli/src/main.rs
index abc9fc1..8b86370 100644
--- a/cli/src/main.rs
+++ b/cli/src/main.rs
@@ -2,7 +2,6 @@ use bytes::Bytes;
 use clap::{Parser, ValueHint};
 use shiva::core::{Document, DocumentType};
 use std::path::Path;
-use std::str::FromStr;
 
 #[derive(Parser, Debug)]
 #[command(
@@ -17,7 +16,7 @@ struct Args {
         value_name = "INPUT_FILE",
         help = &format!(
             "Input file (possible formats: {})",
-            DocumentType::variants_as_str().join(", ")
+            DocumentType::supported_extensions().join(", ")
         ),
         value_hint = ValueHint::FilePath
     )]
@@ -27,7 +26,7 @@ struct Args {
         value_name = "OUTPUT_FILE",
         help = &format!(
             "Output file (possible formats: {})",
-            DocumentType::variants_as_str().join(", ")
+            DocumentType::supported_extensions().join(", ")
         ),
         value_hint = ValueHint::FilePath
     )]
@@ -40,7 +39,7 @@ fn main() -> anyhow::Result<()> {
     let input_path = Path::new(&args.input_file);
     let output_path = Path::new(&args.output_file);
 
-    let supported_formats = DocumentType::variants_as_str();
+    let supported_formats = DocumentType::supported_extensions();
 
     let input_format = match input_path.extension() {
         Some(ext) => ext.to_str().ok_or_else(|| {
@@ -72,7 +71,7 @@ fn main() -> anyhow::Result<()> {
         }
     };
 
-    let input_doc_type = DocumentType::from_str(input_format).map_err(|_| {
+    let input_doc_type = DocumentType::from_extension(input_format).ok_or_else(|| {
         anyhow::anyhow!(
             "Unsupported input file format '{}'. Supported formats are: {}",
             input_format,
@@ -80,7 +79,7 @@ fn main() -> anyhow::Result<()> {
         )
     })?;
 
-    let output_doc_type = DocumentType::from_str(output_format).map_err(|_| {
+    let output_doc_type = DocumentType::from_extension(output_format).ok_or_else(|| {
         anyhow::anyhow!(
             "Unsupported output file format '{}'. Supported formats are: {}",
             output_format,
diff --git a/lib/src/core.rs b/lib/src/core.rs
index 07bf0a0..5192445 100644
--- a/lib/src/core.rs
+++ b/lib/src/core.rs
@@ -1,8 +1,8 @@
 use bytes::Bytes;
 #[cfg(feature = "json")]
 use serde::{Deserialize, Serialize};
-use std::fmt::Debug;
 use std::str::FromStr;
+use std::{collections::HashMap, fmt::Debug};
 use strum::{Display, EnumCount, EnumString, IntoStaticStr, VariantArray};
 use thiserror::Error;
 use wasm_bindgen::prelude::wasm_bindgen;
@@ -774,8 +774,30 @@ impl DocumentType {
         DocumentType::VARIANTS
     }
 
-    pub fn variants_as_str() -> Vec<&'static str> {
-        DocumentType::VARIANTS.iter().map(|v| v.into()).collect()
+    fn extension_map() -> HashMap<&'static str, DocumentType> {
+        let mut map = HashMap::new();
+        map.insert("html", DocumentType::HTML);
+        map.insert("md", DocumentType::Markdown);
+        map.insert("markdown", DocumentType::Markdown);
+        map.insert("txt", DocumentType::Text);
+        map.insert("pdf", DocumentType::PDF);
+        map.insert("json", DocumentType::Json);
+        map.insert("csv", DocumentType::CSV);
+        map.insert("rtf", DocumentType::RTF);
+        map.insert("docx", DocumentType::DOCX);
+        map.insert("xml", DocumentType::XML);
+        map.insert("xls", DocumentType::XLS);
+        map.insert("xlsx", DocumentType::XLSX);
+        map.insert("ods", DocumentType::ODS);
+        map
+    }
+
+    pub fn from_extension(extension: &str) -> Option<DocumentType> {
+        Self::extension_map().get(extension).cloned()
+    }
+
+    pub fn supported_extensions() -> Vec<&'static str> {
+        Self::extension_map().keys().cloned().collect()
     }
 }
 
@@ -820,11 +842,28 @@ mod tests {
     }
 
     #[test]
-    fn test_variants_as_str() {
-        let variants = DocumentType::variants_as_str();
-        assert_eq!(variants.len(), DocumentType::COUNT);
+    fn test_from_extension() {
+        assert_eq!(
+            DocumentType::Markdown,
+            DocumentType::from_extension("md").unwrap()
+        );
+        assert_eq!(
+            DocumentType::Markdown,
+            DocumentType::from_extension("markdown").unwrap()
+        );
+        assert_eq!(
+            DocumentType::Text,
+            DocumentType::from_extension("txt").unwrap()
+        );
+    }
+
+    #[test]
+    fn test_supported_extensions() {
+        let variants = DocumentType::supported_extensions();
         assert!(variants.contains(&"html"));
         assert!(variants.contains(&"docx"));
+        assert!(variants.contains(&"markdown"));
+        assert!(variants.contains(&"md"));
     }
 
     #[test]


Test patch: