1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
use crate::err::Result;
use std::borrow::Cow;
use std::fs;
use std::io::{self, Cursor, Read, Write};
enum FileInner<'a> {
Ram(Cursor<Cow<'a, [u8]>>),
Fs(fs::File),
}
pub struct File<'a> {
inner: FileInner<'a>,
}
pub struct FileMut<'a> {
inner: FileInner<'a>,
}
impl<'a> File<'a> {
pub(crate) fn from_fs(file: fs::File) -> Self {
File {
inner: FileInner::Fs(file),
}
}
pub(crate) fn from_ram<T: Into<Cow<'a, [u8]>>>(ram: T) -> Self {
File {
inner: FileInner::Ram(Cursor::new(ram.into())),
}
}
pub fn as_std(&self) -> Option<&fs::File> {
match &self.inner {
FileInner::Fs(ref file) => Some(file),
_ => None,
}
}
pub fn into_std(self) -> Option<fs::File> {
match self.inner {
FileInner::Fs(file) => Some(file),
_ => None,
}
}
}
impl<'a> FileMut<'a> {
pub(crate) fn from_fs(file: fs::File) -> Self {
FileMut {
inner: FileInner::Fs(file),
}
}
pub fn as_std_mut(&mut self) -> Option<&mut fs::File> {
match &mut self.inner {
FileInner::Fs(ref mut file) => Some(file),
_ => None,
}
}
pub fn as_std(&self) -> Option<&fs::File> {
match &self.inner {
FileInner::Fs(ref file) => Some(file),
_ => None,
}
}
pub fn into_std(self) -> Option<fs::File> {
match self.inner {
FileInner::Fs(file) => Some(file),
_ => None,
}
}
}
impl<'a> Read for File<'a> {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
match &mut self.inner {
FileInner::Ram(ram) => ram.read(buf),
FileInner::Fs(fs) => fs.read(buf),
}
}
}
impl<'a> Write for FileMut<'a> {
#[inline]
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
match &mut self.inner {
FileInner::Fs(fs) => fs.write(buf),
_ => Err(write_support_err()),
}
}
#[inline]
fn flush(&mut self) -> io::Result<()> {
match &mut self.inner {
FileInner::Fs(fs) => fs.flush(),
_ => Err(write_support_err()),
}
}
}
pub fn write_support_err() -> io::Error {
io::Error::new(io::ErrorKind::Other, "Operation not supported.")
}