1use crate::{expect, from_str, ProcResult};
2#[cfg(feature = "serde1")]
3use serde::{Deserialize, Serialize};
4use std::io::BufRead;
5
6#[derive(Debug, Clone)]
16#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
17pub struct DiskStat {
18 pub major: i32,
20
21 pub minor: i32,
23
24 pub name: String,
26
27 pub reads: u64,
31
32 pub merged: u64,
36
37 pub sectors_read: u64,
41
42 pub time_reading: u64,
44
45 pub writes: u64,
47
48 pub writes_merged: u64,
52
53 pub sectors_written: u64,
55
56 pub time_writing: u64,
58
59 pub in_progress: u64,
61
62 pub time_in_progress: u64,
64
65 pub weighted_time_in_progress: u64,
67
68 pub discards: Option<u64>,
72
73 pub discards_merged: Option<u64>,
75
76 pub sectors_discarded: Option<u64>,
78
79 pub time_discarding: Option<u64>,
81
82 pub flushes: Option<u64>,
86
87 pub time_flushing: Option<u64>,
89}
90
91#[derive(Debug, Clone)]
93#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
94pub struct DiskStats(pub Vec<DiskStat>);
95
96impl crate::FromBufRead for DiskStats {
97 fn from_buf_read<R: BufRead>(r: R) -> ProcResult<Self> {
98 let mut v = Vec::new();
99
100 for line in r.lines() {
101 let line = line?;
102 v.push(DiskStat::from_line(&line)?);
103 }
104 Ok(DiskStats(v))
105 }
106}
107
108impl DiskStat {
109 pub fn from_line(line: &str) -> ProcResult<DiskStat> {
110 let mut s = line.split_whitespace();
111
112 let major = from_str!(i32, expect!(s.next()));
113 let minor = from_str!(i32, expect!(s.next()));
114 let name = expect!(s.next()).to_string();
115 let reads = from_str!(u64, expect!(s.next()));
116 let merged = from_str!(u64, expect!(s.next()));
117 let sectors_read = from_str!(u64, expect!(s.next()));
118 let time_reading = from_str!(u64, expect!(s.next()));
119 let writes = from_str!(u64, expect!(s.next()));
120 let writes_merged = from_str!(u64, expect!(s.next()));
121 let sectors_written = from_str!(u64, expect!(s.next()));
122 let time_writing = from_str!(u64, expect!(s.next()));
123 let in_progress = from_str!(u64, expect!(s.next()));
124 let time_in_progress = from_str!(u64, expect!(s.next()));
125 let weighted_time_in_progress = from_str!(u64, expect!(s.next()));
126 let discards = s.next().and_then(|s| u64::from_str_radix(s, 10).ok());
127 let discards_merged = s.next().and_then(|s| u64::from_str_radix(s, 10).ok());
128 let sectors_discarded = s.next().and_then(|s| u64::from_str_radix(s, 10).ok());
129 let time_discarding = s.next().and_then(|s| u64::from_str_radix(s, 10).ok());
130 let flushes = s.next().and_then(|s| u64::from_str_radix(s, 10).ok());
131 let time_flushing = s.next().and_then(|s| u64::from_str_radix(s, 10).ok());
132
133 Ok(DiskStat {
134 major,
135 minor,
136 name,
137 reads,
138 merged,
139 sectors_read,
140 time_reading,
141 writes,
142 writes_merged,
143 sectors_written,
144 time_writing,
145 in_progress,
146 time_in_progress,
147 weighted_time_in_progress,
148 discards,
149 discards_merged,
150 sectors_discarded,
151 time_discarding,
152 flushes,
153 time_flushing,
154 })
155 }
156}