novel_cli/utils/
check.rs

1use std::path::{Path, PathBuf};
2
3use color_eyre::eyre::{self, Result};
4
5pub fn ensure_executable_exists<T>(name: T) -> Result<()>
6where
7    T: AsRef<str>,
8{
9    let name = name.as_ref();
10
11    if let Err(error) = which::which(name) {
12        eyre::bail!("{}: `{}`", error, name);
13    }
14
15    Ok(())
16}
17
18pub fn ensure_epub_file<T>(path: T) -> Result<()>
19where
20    T: AsRef<Path>,
21{
22    if !is_epub_file(&path)? {
23        eyre::bail!("File `{}` is not epub file", path.as_ref().display())
24    }
25
26    Ok(())
27}
28
29pub fn ensure_epub_dir<T>(path: T) -> Result<()>
30where
31    T: AsRef<Path>,
32{
33    if !is_epub_dir(&path)? {
34        eyre::bail!(
35            "Directory `{}` is not epub directory",
36            path.as_ref().display()
37        )
38    }
39
40    Ok(())
41}
42
43pub fn is_markdown_or_txt_file<T>(path: T) -> Result<bool>
44where
45    T: AsRef<Path>,
46{
47    Ok(is_some_file(&path, "md")? || is_some_file(&path, "txt")?)
48}
49
50pub fn is_epub_file<T>(path: T) -> Result<bool>
51where
52    T: AsRef<Path>,
53{
54    is_some_file(path, "epub")
55}
56
57pub fn try_get_markdown_or_txt_file_name_in_dir<T>(path: T) -> Result<Option<PathBuf>>
58where
59    T: AsRef<Path>,
60{
61    let path = path.as_ref();
62
63    ensure_exists(path)?;
64
65    let markdown_file_name = PathBuf::from(path.file_stem().unwrap()).with_extension("md");
66    let markdown_file_path = path.join(markdown_file_name);
67
68    let txt_file_name = PathBuf::from(path.file_stem().unwrap()).with_extension("txt");
69    let txt_file_path = path.join(txt_file_name);
70
71    if markdown_file_path.is_file() && txt_file_path.is_file() {
72        eyre::bail!("Both markdown and txt files exist in the directory");
73    }
74
75    if markdown_file_path.is_file() {
76        Ok(Some(dunce::canonicalize(markdown_file_path)?))
77    } else if txt_file_path.is_file() {
78        Ok(Some(dunce::canonicalize(txt_file_path)?))
79    } else {
80        Ok(None)
81    }
82}
83
84pub fn is_mdbook_dir<T>(path: T) -> Result<bool>
85where
86    T: AsRef<Path>,
87{
88    let path = path.as_ref();
89
90    ensure_exists(path)?;
91
92    if !path.is_dir() {
93        return Ok(false);
94    }
95
96    let src_path = path.join("src");
97    let toml_path = path.join("book.toml");
98
99    Ok(src_path.is_dir() && toml_path.is_file())
100}
101
102pub fn is_epub_dir<T>(path: T) -> Result<bool>
103where
104    T: AsRef<Path>,
105{
106    let path = path.as_ref();
107
108    ensure_exists(path)?;
109
110    if !path.is_dir() {
111        return Ok(false);
112    }
113
114    let epub_path = path.join("EPUB");
115    let meta_path = path.join("META-INF");
116    let mimetype_path = path.join("mimetype");
117
118    Ok(epub_path.is_dir() && meta_path.is_dir() && mimetype_path.is_file())
119}
120
121fn is_some_file<T, E>(path: T, extension: E) -> Result<bool>
122where
123    T: AsRef<Path>,
124    E: AsRef<str>,
125{
126    let path = path.as_ref();
127
128    ensure_exists(path)?;
129
130    if !path.is_file() {
131        return Ok(false);
132    }
133
134    Ok(path
135        .extension()
136        .is_some_and(|ext| ext == extension.as_ref()))
137}
138
139fn ensure_exists<T>(path: T) -> Result<()>
140where
141    T: AsRef<Path>,
142{
143    let path = path.as_ref();
144
145    eyre::ensure!(
146        path.try_exists()?,
147        "File or directory `{}` does not exist",
148        path.display()
149    );
150
151    Ok(())
152}
153
154pub fn ensure_pandoc_dir<T>(path: T) -> Result<()>
155where
156    T: AsRef<Path>,
157{
158    if !is_pandoc_dir(&path)? {
159        eyre::bail!(
160            "Directory `{}` is not pandoc directory",
161            path.as_ref().display()
162        )
163    }
164
165    Ok(())
166}
167
168pub fn ensure_mdbook_dir<T>(path: T) -> Result<()>
169where
170    T: AsRef<Path>,
171{
172    if !is_mdbook_dir(&path)? {
173        eyre::bail!(
174            "Directory `{}` is not mdbook directory",
175            path.as_ref().display()
176        )
177    }
178
179    Ok(())
180}
181
182pub fn is_pandoc_dir<T>(path: T) -> Result<bool>
183where
184    T: AsRef<Path>,
185{
186    let path = path.as_ref();
187
188    ensure_exists(path)?;
189
190    if !path.is_dir() {
191        return Ok(false);
192    }
193
194    let markdown = path.join(path.file_stem().unwrap()).with_extension("md");
195
196    Ok(markdown.is_file())
197}