file_storage/op/file/read/
read_string.rs

1use crate::Operation::Read;
2use crate::Reason::{FileContentNotUTF8, FileNotFound};
3use crate::{Error, FilePath};
4
5impl FilePath {
6    //! Read String
7
8    /// Reads the file as a `String`.
9    ///
10    /// Returns `Ok(file_content)`.
11    /// Returns `Err(FileNotFound)` if the file did not exist.
12    pub fn read_as_string(&self) -> Result<String, Error> {
13        if let Some(file_content) = self.read_as_string_if_exists()? {
14            Ok(file_content)
15        } else {
16            Err(Error::new(self.clone(), Read, FileNotFound))
17        }
18    }
19
20    /// Reads the file as a `String` if it exists.
21    ///
22    /// Returns `Ok(Some(file_content))`.
23    /// Returns `Ok(None)` if the file did not exist.
24    pub fn read_as_string_if_exists(&self) -> Result<Option<String>, Error> {
25        if let Some(file_content) = self.read_as_vec_if_exists()? {
26            match String::from_utf8(file_content) {
27                Ok(file_content) => Ok(Some(file_content)),
28                Err(_) => Err(Error::new(self.clone(), Read, FileContentNotUTF8)),
29            }
30        } else {
31            Ok(None)
32        }
33    }
34
35    /// Reads the file to the `target` `String`.
36    ///
37    /// Returns `Ok(file_content_len)`.
38    /// Returns `Err(FileNotFound)` if the file did not exist.
39    pub fn read_to_string(&self, target: &mut String) -> Result<usize, Error> {
40        if let Some(file_content_len) = self.read_to_string_if_exists(target)? {
41            Ok(file_content_len)
42        } else {
43            Err(Error::new(self.clone(), Read, FileNotFound))
44        }
45    }
46
47    /// Reads the file to the `target` `String` if it exists.
48    ///
49    /// Returns `Ok(Some(file_content_len))`.
50    /// Returns `Ok(None)` if the file did not exist.
51    pub fn read_to_string_if_exists(&self, target: &mut String) -> Result<Option<usize>, Error> {
52        // todo -- check unsafe with panics
53        let target: &mut Vec<u8> = unsafe { target.as_mut_vec() };
54        let original_len: usize = target.len();
55        match self.read_to_vec_if_exists(target) {
56            Ok(file_content_len) => {
57                if let Some(file_content_len) = file_content_len {
58                    debug_assert_eq!(target.len(), original_len + file_content_len);
59                    let slice: &[u8] = &target[original_len..];
60                    match std::str::from_utf8(slice) {
61                        Ok(_) => Ok(Some(file_content_len)),
62                        Err(_) => {
63                            target.truncate(original_len);
64                            Err(Error::new(self.clone(), Read, FileContentNotUTF8))
65                        }
66                    }
67                } else {
68                    Ok(None)
69                }
70            }
71            Err(e) => {
72                target.truncate(original_len);
73                Err(e)
74            }
75        }
76    }
77}