sysctl/traits.rs
1// traits.rs
2
3use ctl_error::SysctlError;
4use ctl_flags::CtlFlags;
5use ctl_info::CtlInfo;
6use ctl_type::CtlType;
7use ctl_value::CtlValue;
8
9pub trait Sysctl {
10 /// Construct a Ctl from the name.
11 ///
12 /// Returns a result containing the struct Ctl on success or a SysctlError
13 /// on failure.
14 ///
15 /// # Example
16 /// ```
17 /// # use sysctl::Sysctl;
18 /// #
19 /// let ctl = sysctl::Ctl::new("kern.ostype");
20 /// ```
21 ///
22 /// If the sysctl does not exist, `Err(SysctlError::NotFound)` is returned.
23 /// ```
24 /// # use sysctl::Sysctl;
25 /// #
26 /// let ctl = sysctl::Ctl::new("this.sysctl.does.not.exist");
27 /// match ctl {
28 /// Err(sysctl::SysctlError::NotFound(_)) => (),
29 /// Err(e) => panic!(format!("Wrong error type returned: {:?}", e)),
30 /// Ok(_) => panic!("Nonexistent sysctl seems to exist"),
31 /// }
32 /// ```
33 fn new(name: &str) -> Result<Self, SysctlError>
34 where
35 Self: std::marker::Sized;
36
37 /// Construct a Ctl from the name, type and format.
38 ///
39 /// Returns a result containing the struct Ctl on success or a SysctlError
40 /// on failure.
41 ///
42 /// # Example
43 /// ```
44 /// # use sysctl::{CtlType, Sysctl};
45 /// #
46 /// let ctl = sysctl::Ctl::new_with_type("kern.ostype", CtlType::String, "");
47 /// ```
48 ///
49 /// If the sysctl does not exist, `Err(SysctlError::NotFound)` is returned.
50 /// ```
51 /// # use sysctl::{CtlType, Sysctl};
52 /// #
53 /// let ctl = sysctl::Ctl::new_with_type("this.sysctl.does.not.exist", CtlType::String, "");
54 /// match ctl {
55 /// Err(sysctl::SysctlError::NotFound(_)) => (),
56 /// Err(e) => panic!("Wrong error type returned: {:?}", e),
57 /// Ok(_) => panic!("Nonexistent sysctl seems to exist"),
58 /// }
59 /// ```
60 fn new_with_type(name: &str, ctl_type: CtlType, fmt: &str) -> Result<Self, SysctlError>
61 where
62 Self: std::marker::Sized;
63
64 /// Returns a result containing the sysctl name on success, or a
65 /// SysctlError on failure.
66 ///
67 /// # Example
68 /// ```
69 /// # use sysctl::Sysctl;
70 /// if let Ok(ctl) = sysctl::Ctl::new("kern.ostype") {
71 /// assert_eq!(ctl.name().unwrap(), "kern.ostype");
72 /// }
73 /// ```
74 fn name(&self) -> Result<String, SysctlError>;
75
76 /// Returns a result containing the sysctl value type on success,
77 /// or a Sysctl Error on failure.
78 ///
79 /// # Example
80 ///
81 /// ```
82 /// # use sysctl::Sysctl;
83 /// if let Ok(ctl) = sysctl::Ctl::new("kern.ostype") {
84 /// let value_type = ctl.value_type().unwrap();
85 /// assert_eq!(value_type, sysctl::CtlType::String);
86 /// }
87 /// ```
88 fn value_type(&self) -> Result<CtlType, SysctlError>;
89
90 /// Returns a result containing the sysctl description if success, or an
91 /// Error on failure.
92 ///
93 /// # Example
94 /// ```
95 /// # use sysctl::Sysctl;
96 /// if let Ok(ctl) = sysctl::Ctl::new("kern.ostype") {
97 /// println!("Description: {:?}", ctl.description())
98 /// }
99 /// ```
100 fn description(&self) -> Result<String, SysctlError>;
101
102 /// Returns a result containing the sysctl value on success, or a
103 /// SysctlError on failure.
104 ///
105 /// # Example
106 /// ```
107 /// # use sysctl::Sysctl;
108 /// if let Ok(ctl) = sysctl::Ctl::new("kern.ostype") {
109 /// println!("Value: {:?}", ctl.value());
110 /// }
111 /// ```
112 fn value(&self) -> Result<CtlValue, SysctlError>;
113
114 /// A generic method that takes returns a result containing the sysctl
115 /// value if success, or a SysctlError on failure.
116 ///
117 /// May only be called for sysctls of type Opaque or Struct.
118 /// # Example
119 /// ```
120 /// # use sysctl::Sysctl;
121 /// #[derive(Debug)]
122 /// #[repr(C)]
123 /// struct ClockInfo {
124 /// hz: libc::c_int, /* clock frequency */
125 /// tick: libc::c_int, /* micro-seconds per hz tick */
126 /// spare: libc::c_int,
127 /// stathz: libc::c_int, /* statistics clock frequency */
128 /// profhz: libc::c_int, /* profiling clock frequency */
129 /// }
130 ///
131 /// if let Ok(ctl) = sysctl::Ctl::new("kern.clockrate") {
132 /// println!("{:?}", ctl.value_as::<ClockInfo>());
133 /// }
134 /// ```
135 fn value_as<T>(&self) -> Result<Box<T>, SysctlError>;
136
137 /// Returns a result containing the sysctl value as String on
138 /// success, or a SysctlError on failure.
139 ///
140 /// # Example
141 /// ```
142 /// # use sysctl::Sysctl;
143 /// if let Ok(ctl) = sysctl::Ctl::new("kern.osrevision") {
144 /// println!("Value: {:?}", ctl.value_string());
145 /// }
146 /// ```
147 fn value_string(&self) -> Result<String, SysctlError>;
148
149 #[cfg_attr(feature = "cargo-clippy", allow(clippy::needless_doctest_main))]
150 /// Sets the value of a sysctl.
151 /// Fetches and returns the new value if successful, or returns a
152 /// SysctlError on failure.
153 /// # Example
154 /// ```
155 /// use sysctl::Sysctl;
156 ///
157 /// fn main() {
158 /// if unsafe { libc::getuid() } == 0 {
159 /// if let Ok(ctl) = sysctl::Ctl::new("hw.usb.debug") {
160 /// let org = ctl.value().unwrap();
161 /// let set = ctl.set_value(sysctl::CtlValue::Int(1)).unwrap();
162 /// assert_eq!(set, sysctl::CtlValue::Int(1));
163 /// ctl.set_value(org).unwrap();
164 /// }
165 /// }
166 /// }
167 fn set_value(&self, value: CtlValue) -> Result<CtlValue, SysctlError>;
168
169 #[cfg_attr(feature = "cargo-clippy", allow(clippy::needless_doctest_main))]
170 /// Sets the value of a sysctl with input as string.
171 /// Fetches and returns the new value if successful, or returns a
172 /// SysctlError on failure.
173 /// # Example
174 /// ```
175 /// use sysctl::Sysctl;
176 ///
177 /// fn main() {
178 /// if unsafe { libc::getuid() } == 0 {
179 /// if let Ok(ctl) = sysctl::Ctl::new("hw.usb.debug") {
180 /// let org = ctl.value_string().unwrap();
181 /// let set = ctl.set_value_string("1");
182 /// println!("hw.usb.debug: -> {:?}", set);
183 /// ctl.set_value_string(&org).unwrap();
184 /// }
185 /// }
186 /// }
187 fn set_value_string(&self, value: &str) -> Result<String, SysctlError>;
188
189 /// Get the flags for a sysctl.
190 ///
191 /// Returns a Result containing the flags on success,
192 /// or a SysctlError on failure.
193 ///
194 /// # Example
195 /// ```
196 /// # use sysctl::Sysctl;
197 /// if let Ok(ctl) = sysctl::Ctl::new("kern.ostype") {
198 /// let readable = ctl.flags().unwrap().contains(sysctl::CtlFlags::RD);
199 /// assert!(readable);
200 /// }
201 /// ```
202 fn flags(&self) -> Result<CtlFlags, SysctlError>;
203
204 #[cfg_attr(feature = "cargo-clippy", allow(clippy::needless_doctest_main))]
205 /// Returns a Result containing the control metadata for a sysctl.
206 ///
207 /// Returns a Result containing the CtlInfo struct on success,
208 /// or a SysctlError on failure.
209 ///
210 /// # Example
211 /// ```
212 /// use sysctl::Sysctl;
213 ///
214 /// fn main() {
215 /// if let Ok(ctl) = sysctl::Ctl::new("kern.osrevision") {
216 /// let info = ctl.info().unwrap();
217 ///
218 /// // kern.osrevision is not a structure.
219 /// assert_eq!(info.struct_type(), None);
220 /// }
221 /// }
222 /// ```
223 fn info(&self) -> Result<CtlInfo, SysctlError>;
224}