nethsm_cli/
passphrase_file.rs

1//! Handling of files containing a [`Passphrase`].
2
3use std::{
4    fs::read_to_string,
5    path::{Path, PathBuf},
6    str::FromStr,
7};
8
9use nethsm::Passphrase;
10
11/// A passphrase file error
12#[derive(Debug, thiserror::Error)]
13pub enum Error {
14    /// An I/O error
15    #[error("I/O error: {0}")]
16    Io(#[from] std::io::Error),
17    /// Path creation error
18    #[error("Path error: {0}")]
19    Path(#[from] core::convert::Infallible),
20}
21
22/// A representation of a file containing a passphrase
23#[derive(Clone, Debug)]
24pub struct PassphraseFile {
25    /// The passphrase contained in the file.
26    pub passphrase: Passphrase,
27}
28
29impl PassphraseFile {
30    /// Creates a new [`PassphraseFile`] from a path.
31    ///
32    /// # Errors
33    ///
34    /// Returns an error if reading the file to string fails.
35    pub fn new(path: &Path) -> Result<Self, Error> {
36        Ok(Self {
37            passphrase: Passphrase::new(read_to_string(path)?),
38        })
39    }
40}
41
42impl FromStr for PassphraseFile {
43    type Err = Error;
44
45    fn from_str(s: &str) -> Result<Self, Self::Err> {
46        PassphraseFile::new(&PathBuf::from_str(s)?)
47    }
48}
49
50#[cfg(test)]
51mod tests {
52    use std::fs::File;
53    use std::io::Write;
54
55    use rand::{Rng, thread_rng};
56    use rstest::rstest;
57    use testdir::testdir;
58    use testresult::TestResult;
59
60    use super::*;
61
62    #[rstest]
63    fn passphrase_file() -> TestResult {
64        let mut i = 0;
65        while i < 20 {
66            let mut rng = thread_rng();
67            let lines = rng.gen_range(0..20);
68            let lines_vec = (0..lines)
69                .map(|_x| "this is a passphrase".to_string())
70                .collect::<Vec<String>>();
71            let path = testdir!().join(format!("passphrase_file_lines_{lines}.txt"));
72            let mut file = File::create(&path)?;
73            file.write_all(lines_vec.join("\n").as_bytes())?;
74
75            let passphrase_file = PassphraseFile::new(&path);
76            assert!(passphrase_file.is_ok());
77            i += 1;
78        }
79
80        Ok(())
81    }
82}