1use std::fmt;
11use std::fs;
12use std::io;
13use std_prelude::*;
14
15use super::open::FileOpen;
16use super::{Error, PathAbs, PathFile, PathInfo, Result};
17
18pub struct FileRead(pub(crate) FileOpen);
44
45impl FileRead {
46 pub fn open<P: AsRef<Path>>(path: P) -> Result<FileRead> {
48 let mut options = fs::OpenOptions::new();
49 options.read(true);
50 Ok(FileRead(FileOpen::open(path, options)?))
51 }
52
53 pub(crate) fn open_abs<P: Into<PathAbs>>(path: P) -> Result<FileRead> {
55 let mut options = fs::OpenOptions::new();
56 options.read(true);
57 Ok(FileRead(FileOpen::open_abs(path, options)?))
58 }
59
60 pub fn path(&self) -> &PathFile {
61 &self.0.path
62 }
63
64 pub fn read_string(&mut self) -> Result<String> {
66 let mut s = String::new();
67 self.0
68 .file
69 .read_to_string(&mut s)
70 .map_err(|err| Error::new(err, "reading", self.0.path.clone().into()))?;
71 Ok(s)
72 }
73}
74
75impl fmt::Debug for FileRead {
76 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
77 write!(f, "FileRead(")?;
78 self.0.path.fmt(f)?;
79 write!(f, ")")
80 }
81}
82
83impl io::Read for FileRead {
84 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
85 self.0.file.read(buf).map_err(|err| {
86 io::Error::new(
87 err.kind(),
88 format!("{} when reading {}", err, self.path().display()),
89 )
90 })
91 }
92}
93
94impl io::Seek for FileRead {
95 fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
96 self.0.file.seek(pos).map_err(|err| {
97 io::Error::new(
98 err.kind(),
99 format!("{} seeking {}", err, self.path().display()),
100 )
101 })
102 }
103}
104
105impl AsRef<FileOpen> for FileRead {
106 fn as_ref(&self) -> &FileOpen {
107 &self.0
108 }
109}
110
111impl AsRef<File> for FileRead {
112 fn as_ref(&self) -> &File {
113 self.0.as_ref()
114 }
115}
116
117impl Borrow<FileOpen> for FileRead {
118 fn borrow(&self) -> &FileOpen {
119 &self.0
120 }
121}
122
123impl Borrow<File> for FileRead {
124 fn borrow(&self) -> &File {
125 self.0.borrow()
126 }
127}
128
129impl<'a> Borrow<FileOpen> for &'a FileRead {
130 fn borrow(&self) -> &FileOpen {
131 &self.0
132 }
133}
134
135impl<'a> Borrow<File> for &'a FileRead {
136 fn borrow(&self) -> &File {
137 self.0.borrow()
138 }
139}
140
141impl From<FileRead> for FileOpen {
142 fn from(orig: FileRead) -> FileOpen {
143 orig.0
144 }
145}
146
147impl From<FileRead> for File {
148 fn from(orig: FileRead) -> File {
149 orig.0.into()
150 }
151}