file_storage/op/file/read/
read_string.rs

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