nu_command/filesystem/
util.rs

1use dialoguer::Input;
2use std::{
3    error::Error,
4    path::{Path, PathBuf},
5};
6
7#[derive(Debug, Eq, Ord, PartialEq, PartialOrd)]
8pub struct Resource {
9    pub at: usize,
10    pub location: PathBuf,
11}
12
13impl Resource {}
14
15pub fn try_interaction(
16    interactive: bool,
17    prompt: String,
18) -> (Result<Option<bool>, Box<dyn Error>>, bool) {
19    let interaction = if interactive {
20        match get_interactive_confirmation(prompt) {
21            Ok(i) => Ok(Some(i)),
22            Err(e) => Err(e),
23        }
24    } else {
25        Ok(None)
26    };
27
28    let confirmed = match interaction {
29        Ok(maybe_input) => maybe_input.unwrap_or(false),
30        Err(_) => false,
31    };
32
33    (interaction, confirmed)
34}
35
36fn get_interactive_confirmation(prompt: String) -> Result<bool, Box<dyn Error>> {
37    let input = Input::new()
38        .with_prompt(prompt)
39        .validate_with(|c_input: &String| -> Result<(), String> {
40            if c_input.len() == 1
41                && (c_input == "y" || c_input == "Y" || c_input == "n" || c_input == "N")
42            {
43                Ok(())
44            } else if c_input.len() > 1 {
45                Err("Enter only one letter (Y/N)".to_string())
46            } else {
47                Err("Input not valid".to_string())
48            }
49        })
50        .default("Y/N".into())
51        .interact_text()?;
52
53    if input == "y" || input == "Y" {
54        Ok(true)
55    } else {
56        Ok(false)
57    }
58}
59
60/// Return `Some(true)` if the last change time of the `src` old than the `dst`,
61/// otherwisie return `Some(false)`. Return `None` if the `src` or `dst` doesn't exist.
62#[allow(dead_code)]
63pub fn is_older(src: &Path, dst: &Path) -> Option<bool> {
64    if !dst.exists() || !src.exists() {
65        return None;
66    }
67    #[cfg(unix)]
68    {
69        use std::os::unix::fs::MetadataExt;
70        let src_ctime = std::fs::metadata(src)
71            .map(|m| m.ctime())
72            .unwrap_or(i64::MIN);
73        let dst_ctime = std::fs::metadata(dst)
74            .map(|m| m.ctime())
75            .unwrap_or(i64::MAX);
76        Some(src_ctime <= dst_ctime)
77    }
78    #[cfg(windows)]
79    {
80        use std::os::windows::fs::MetadataExt;
81        let src_ctime = std::fs::metadata(src)
82            .map(|m| m.last_write_time())
83            .unwrap_or(u64::MIN);
84        let dst_ctime = std::fs::metadata(dst)
85            .map(|m| m.last_write_time())
86            .unwrap_or(u64::MAX);
87        Some(src_ctime <= dst_ctime)
88    }
89}