dd_lib/
results.rs

1//! Structs, enums, and error types for reporting success and failure.
2use opts;
3use std::{borrow::Cow, fmt, time::SystemTime};
4/// A `Result<T, dd::Error>`
5pub type Result<T> = std::result::Result<T, Error>;
6
7#[derive(Debug, PartialEq, Eq, Clone)]
8/// A successful output from [`dd`][super::dd]
9pub enum Success {
10    /// Normal operation reports the number of bytes copied.
11    /// Corresponds to [`opts::Mode::Standard`]
12    Bytes {
13        /// bytes successfuly written
14        bytes: usize,
15        /// start time of operation
16        start: SystemTime,
17    },
18    /// Unblock reports the number of fixed-sized records copied and the block
19    /// size. Corresponds to [`opts::Mode::Unblock`]
20    Unblock {
21        /// number of blocks successfully written
22        blocks: usize,
23        /// block size (in bytes) of fixed-sized records
24        block_size: usize,
25        start: SystemTime,
26    },
27    /// [`opts::Mode::Block`]
28    Block {
29        /// number of newline or EOF-terminated lines
30        lines: usize,
31        /// lines truncated to `block_size`
32        truncated: usize,
33        /// lines padded with spaces to block_size
34        padded: usize,
35        /// block_size (in bytes)
36        block_size: usize,
37        /// system time at start of operation
38        start: SystemTime,
39    },
40}
41#[derive(Debug)]
42/// An Error in operation of [`dd`][super::dd]
43pub enum Error {
44    /// An error while reading, writing, or converting. See [io][super::io].
45    IO(std::io::Error),
46    /// An user input error corresponding to an incorectly specified,
47    /// unimplemented, or conflicting option.
48    Opt(opts::Error),
49}
50
51impl fmt::Display for Error {
52    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
53        match self {
54            Error::IO(err) => write!(f, "io error: {}", err),
55            Error::Opt(err) => write!(f, "command line argument error: {}", err),
56        }
57    }
58}
59
60impl From<std::io::Error> for Error {
61    fn from(err: ::std::io::Error) -> Self { Error::IO(err) }
62}
63impl From<opts::Error> for Error {
64    fn from(err: opts::Error) -> Self { Error::Opt(err) }
65}
66impl std::error::Error for Error {}
67impl fmt::Display for Success {
68    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
69        match self {
70            Success::Bytes { bytes, start } => write!(f, "wrote {} bytes in {}", bytes, elapsed(start)),
71            Success::Block {
72                lines,
73                truncated,
74                padded,
75                block_size,
76                start,
77            } => write!(
78                f,
79                concat!(
80                    "Wrote {lines} lines of length {len} in {seconds}.\n",
81                    "Padded {padded}/{len} lines\n",
82                    "Truncated {truncated}/{len} lines\n"
83                ),
84                lines = lines,
85                truncated = truncated,
86                len = block_size,
87                padded = padded,
88                seconds = elapsed(start),
89            ),
90            Success::Unblock {
91                blocks,
92                block_size,
93                start,
94            } => write!(
95                f,
96                "wrote {} records of fixed size {} in {}",
97                blocks,
98                block_size,
99                elapsed(start)
100            ),
101        }
102    }
103}
104
105//// the elapsed time in seconds, with three decimal digits of precision
106pub fn elapsed(start: &SystemTime) -> Cow<'static, str> {
107    match start.elapsed() {
108        Ok(elapsed) => Cow::Owned(format!("{}.{:03} seconds", elapsed.as_secs(), elapsed.subsec_millis())),
109        _ => Cow::Borrowed("<error obtaining elapsed time>"),
110    }
111}