dd_lib/opts/flags/
iflag.rs

1use super::{Kind, Result, Unimplemented};
2bitflags! {
3    /// - append:  append mode (makes sense only for output; conv=notrunc
4    /// suggested)
5    ///
6    /// - direct:  use direct I/O for data
7    ///
8    /// - directory:  fail unless a directory
9    ///
10    /// - dsync:  use synchronized I/O for data
11    ///
12    /// - sync:  use synchronized io for data AND metadata
13    ///
14    /// - fullblock:  accumulate full blocks of input
15    ///
16    /// - nonblock:  use non-blocking I/O
17    ///
18    /// - noatime:  do not update access time
19    ///
20    /// - nocache:  Request to drop cache.  See also oflag=sync
21    ///
22    /// - noctty:  do not assign controlling terminal from file
23    ///
24    /// - nofollow:  do not follow symlinks
25    ///
26    /// - count_bytes:  treat 'count=N' as a byte count
27    ///
28    /// - skip_bytes:  treat 'skip=N' as a byte count
29    pub struct IFlag: u32 {
30        /// append mode (makes sense only for output; conv=notrunc suggested)
31        const APPEND = 0x0001;
32        /// <NOT IMPLEMENTED> use direct I/O for data
33        const DIRECT = 0x0002;
34        /// fail unless a directory
35        const DIRECTORY = 0x0004;
36        /// <NOT IMPLEMENTED> use synchronized I/O for data
37        const DSYNC = 0x0008;
38        /// <UNIMPLMEMENTED> use synchronized I/O for data and metadata
39        const SYNC =0x0010;
40        /// accumulate full blocks of input (iflag only)
41        const FULLBLOCK= 0x0020;
42        /// <NOT IMPLEMENTED> use non-blocking I/O
43        const NONBLOCK = 0x0040;
44        /// <NOT IMPLEMENTED> do not update access time
45        const NOATIME = 0x0080;
46        /// <NOT IMPLEMENTED> Request to drop cache.  See also oflag=sync
47        const NOCACHE = 0x0100;
48        /// <NOT IMPLEMENTED> do not assign controlling terminal from file
49        const NOCTTY = 0x0200;
50        /// <NOT IMPLEMENTED> do not follow symlinks
51        const NOFOLLOW = 0x0400;
52        /// treat 'count=N' as a byte count (iflag only)
53        const COUNT_BYTES = 0x0800;
54        /// treat 'skip=N' as a byte count (iflag only)
55        const SKIP_BYTES = 0x1000;
56    }
57}
58
59impl IFlag {
60    // Unimplemented iflags
61
62    /// create a new `opts::IFlag` by parsing a comma-and-optional-whitespace
63    /// separated list of arguments ```
64    /// #use dd:opts;
65    /// assert_eq!(opts::In::new("directory,  append  ").unwrap(),
66    /// opts::IFlag::DIRECTORY | opts::IFlag::APPEND); ```
67    pub fn new(s: &str) -> Result<Self> {
68        let mut flags = Self::default();
69        for flag in s.split(',').map(str::trim).filter(|s| s.len() > 0) {
70            Self::check_if_implemented(flag)?;
71            flags |= { Self::from_str(flag)? };
72        }
73        Ok(flags)
74    }
75
76    fn from_str(flag: &str) -> Result<Self> {
77        Ok(match flag {
78            "append" => Self::APPEND,
79            "directory" => Self::DIRECTORY,
80            "dsync" => Self::DSYNC,
81            "sync" => Self::SYNC,
82            "fullblock" => Self::FULLBLOCK,
83            "nonblock" => Self::NONBLOCK,
84            "noatime" => Self::NOATIME,
85            "nocache" => Self::NOCACHE,
86            "noctty" => Self::NOCTTY,
87            "nofollow" => Self::NOFOLLOW,
88            "count_bytes" => Self::COUNT_BYTES,
89            "skip_bytes" => Self::SKIP_BYTES,
90            _ => return Self::unknown(flag.to_owned()),
91        })
92    }
93}
94
95impl Default for IFlag {
96    fn default() -> IFlag { IFlag::empty() }
97}
98
99impl Unimplemented for IFlag {
100    const KIND: Kind = Kind::IFlag;
101    const UNIMPLEMENTED: &'static [&'static str] = &[
102        "direct",
103        "directory",
104        "dync",
105        "noatime",
106        "nocache",
107        "nofollow",
108        "noctty",
109        "nonblock",
110        "fullblock",
111    ];
112}