1use serde::{Deserialize, Serialize};
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
17#[serde(rename_all = "snake_case")]
18#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
19pub enum Format {
20 Markdown,
23 Plain,
25}
26
27const MARKDOWN_EXTENSIONS: [&str; 2] = ["md", "markdown"];
29
30impl Format {
31 pub fn of_name(name: &str) -> Format {
33 let last = name.rsplit(['/', '\\']).next().unwrap_or(name);
34 let markdown = last.rsplit_once('.').is_some_and(|(stem, extension)| {
35 !stem.is_empty()
36 && MARKDOWN_EXTENSIONS
37 .iter()
38 .any(|known| known.eq_ignore_ascii_case(extension))
39 });
40 if markdown {
41 Format::Markdown
42 } else {
43 Format::Plain
44 }
45 }
46}
47
48#[cfg(test)]
49#[allow(
50 clippy::unwrap_used,
51 clippy::expect_used,
52 clippy::panic,
53 clippy::indexing_slicing,
54 reason = "test code"
55)]
56mod tests {
57 use super::*;
58
59 #[test]
60 fn the_extension_of_the_last_segment_decides() {
61 assert_eq!(Format::of_name("lab/Roadmap.md"), Format::Markdown);
62 assert_eq!(Format::of_name("lab/NOTES.Markdown"), Format::Markdown);
63 assert_eq!(Format::of_name("lab/notes.txt"), Format::Plain);
64 assert_eq!(Format::of_name("lab.md/notes"), Format::Plain);
65 assert_eq!(Format::of_name(".md"), Format::Plain);
66 }
67}