dd_lib/opts/flags/
oflag.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   likewise, but also for metadata
13    ///
14    /// - nonblock:  use non-blocking I/O
15    ///
16    /// - noatime:  do not update access time
17    ///
18    /// - nocache:  Request to drop cache.  See also oflag=sync
19    ///
20    /// - noctty:  do not assign controlling terminal from file
21    ///
22    /// - nofollow:  do not follow symlinks
23    ///
24    /// - seek_bytes: treat 'seek=N' as a byte count (oflag only)
25    ///
26    ///
27    pub struct OFlag: u32 {
28        /// append mode (makes sense only for output; conv=notrunc suggested)
29        const APPEND = 0x0001;
30        /// use direct I/O for data
31        const DIRECT = 0x0002;
32        /// fail unless a directory
33        const DIRECTORY = 0x0004;
34        /// use synchronized I/O for data
35        const DSYNC = 0x0008;
36        /// likewise, but also for metadata
37        const SYNC = 0x0010;
38        /// use non-blocking I/O
39        const NONBLOCK = 0x0020;
40        /// do not update access time
41        const NOATIME = 0x0040;
42        /// Request to drop cache.  See also oflag=sync
43        const NOCACHE = 0x0080;
44        /// do not assign controlling terminal from file
45        const NOCTTY = 0x0100;
46        /// do not follow symlinks
47        const NOFOLLOW = 0x0200;
48    }
49}
50impl OFlag {
51    /// create a new `flags::OFlag` by parsing a comma-and-optional-whitespace
52    /// separated list of arguments ```
53    /// #use dd:opts::flags;
54    /// assert_eq!(flags::OFlag::new("directory,  append  ").unwrap(),
55    /// flags::OFlag::DIRECTORY | flags::In::APPEND); ```
56    #[allow(unreachable_patterns)]
57    pub fn new(s: &str) -> Result<Self> {
58        let mut flags = Self::default();
59
60        for flag in s.split(',').map(str::trim).filter(|s| s.len() > 0) {
61            Self::check_if_implemented(flag)?;
62            flags |= Self::from_str(flag)?;
63        }
64        Ok(flags)
65    }
66
67    fn from_str(flag: &str) -> Result<Self> {
68        Ok(match flag {
69            "append" => Self::APPEND,
70            "sync" => Self::SYNC,
71            "direct" => Self::DIRECT,
72            "directory" => Self::DIRECTORY,
73            "dsync" => Self::DSYNC,
74            "nonblock" => Self::NONBLOCK,
75            "noatime" => Self::NOATIME,
76            "nocache" => Self::NOCACHE,
77            "noctty" => Self::NOCTTY,
78            "nofollow" => Self::NOFOLLOW,
79            f => return Self::unknown(f.to_owned()),
80        })
81    }
82}
83
84impl Default for OFlag {
85    fn default() -> OFlag { OFlag::empty() }
86}
87
88impl Unimplemented for OFlag {
89    const KIND: Kind = Kind::OFlag;
90    const UNIMPLEMENTED: &'static [&'static str] = &[
91        "direct",
92        "directory",
93        "dsync",
94        "nonblock",
95        "noatime",
96        "nocache",
97        "noctty",
98        "nofollow",
99    ];
100}