1use crate::args;
4use crate::error::ModCliError;
5use std::path::Path;
6use std::str::FromStr;
7
8pub fn require(argsv: &[String], name: &str) -> Result<(), ModCliError> {
10 if args::flag(argsv, name) || args::get_string(argsv, name).is_some() {
11 Ok(())
12 } else {
13 Err(ModCliError::InvalidUsage(format!(
14 "missing required argument: {name}"
15 )))
16 }
17}
18
19pub fn parse_in_range<T>(
21 argsv: &[String],
22 name: &str,
23 min: Option<T>,
24 max: Option<T>,
25) -> Result<T, ModCliError>
26where
27 T: FromStr + PartialOrd + Copy + std::fmt::Display,
28{
29 let val: T = args::get_int(argsv, name)?; if let Some(lo) = min {
31 if val < lo {
32 return Err(ModCliError::InvalidUsage(format!(
33 "{name} below minimum ({val} < {lo})"
34 )));
35 }
36 }
37 if let Some(hi) = max {
38 if val > hi {
39 return Err(ModCliError::InvalidUsage(format!(
40 "{name} above maximum ({val} > {hi})"
41 )));
42 }
43 }
44 Ok(val)
45}
46
47pub fn path_exists(p: &str) -> Result<(), ModCliError> {
49 if Path::new(p).exists() {
50 Ok(())
51 } else {
52 Err(ModCliError::InvalidUsage(format!(
53 "path does not exist: {p}"
54 )))
55 }
56}
57
58pub fn path_is_file(p: &str) -> Result<(), ModCliError> {
60 let path = Path::new(p);
61 if path.is_file() {
62 Ok(())
63 } else {
64 Err(ModCliError::InvalidUsage(format!("not a file: {p}")))
65 }
66}
67
68pub fn path_is_dir(p: &str) -> Result<(), ModCliError> {
70 let path = Path::new(p);
71 if path.is_dir() {
72 Ok(())
73 } else {
74 Err(ModCliError::InvalidUsage(format!("not a directory: {p}")))
75 }
76}