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}