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
110
111
use super::MountInfo;
use std::io;
use std::fmt::{self, Display, Formatter};
use std::str::FromStr;
use std::ops::{Deref, DerefMut};
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum AbstractMountElement {
Comment(String),
Empty,
Mount(MountInfo)
}
impl Display for AbstractMountElement {
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result<> {
match self {
AbstractMountElement::Comment(ref comment) => fmt.write_str(comment),
AbstractMountElement::Empty => Ok(()),
AbstractMountElement::Mount(ref entry) => fmt.write_fmt(format_args!("{}", entry))
}
}
}
impl From<String> for AbstractMountElement {
fn from(comment: String) -> Self {
AbstractMountElement::Comment(comment)
}
}
impl From<()> for AbstractMountElement {
fn from(_: ()) -> Self {
AbstractMountElement::Empty
}
}
impl From<MountInfo> for AbstractMountElement {
fn from(info: MountInfo) -> Self {
AbstractMountElement::Mount(info)
}
}
#[derive(Clone, Default, Debug, Eq, PartialEq)]
pub struct MountTab(pub Vec<AbstractMountElement>);
impl MountTab {
pub fn iter_mounts(&self) -> impl Iterator<Item = &MountInfo> {
self.0.iter().filter_map(|e| if let AbstractMountElement::Mount(e) = e { Some(e) } else { None })
}
pub fn iter_mounts_mut(&mut self) -> impl Iterator<Item = &mut MountInfo> {
self.0.iter_mut().filter_map(|e| if let AbstractMountElement::Mount(e) = e { Some(e) } else { None })
}
pub fn push<E: Into<AbstractMountElement>>(&mut self, element: E) {
self.0.push(element.into());
}
}
impl Deref for MountTab {
type Target = Vec<AbstractMountElement>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for MountTab {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl Display for MountTab {
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
for entry in &self.0 {
writeln!(fmt, "{}", entry)?;
}
Ok(())
}
}
impl FromStr for MountTab {
type Err = io::Error;
fn from_str(input: &str) -> Result<Self, Self::Err> {
let mut entries = Vec::new();
for line in input.lines() {
let line = line.trim_start();
if line.is_empty() {
entries.push(AbstractMountElement::Empty);
} else if line.starts_with('#') {
entries.push(AbstractMountElement::Comment(line.to_owned()));
} else {
let info = line.parse::<MountInfo>()?;
entries.push(AbstractMountElement::Mount(info));
}
}
Ok(MountTab(entries))
}
}