sysinfo/
traits.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use crate::{
4    common::{Gid, MacAddr, Uid},
5    sys::{Component, Cpu, Disk, Networks, Process},
6};
7use crate::{
8    CpuRefreshKind, DiskKind, DiskUsage, LoadAvg, NetworksIter, Pid, ProcessRefreshKind,
9    ProcessStatus, RefreshKind, Signal, User,
10};
11
12use std::collections::HashMap;
13use std::ffi::OsStr;
14use std::fmt::Debug;
15use std::path::Path;
16use std::time::Duration;
17
18/// Contains all the methods of the [`Disk`][crate::Disk] struct.
19///
20/// ```no_run
21/// use sysinfo::{DiskExt, System, SystemExt};
22///
23/// let mut s = System::new();
24/// s.refresh_disks_list();
25/// for disk in s.disks() {
26///     println!("{:?}: {:?}", disk.name(), disk.kind());
27/// }
28/// ```
29pub trait DiskExt: Debug {
30    /// Returns the kind of disk.
31    ///
32    /// ```no_run
33    /// use sysinfo::{DiskExt, System, SystemExt};
34    ///
35    /// let mut s = System::new();
36    /// s.refresh_disks_list();
37    /// for disk in s.disks() {
38    ///     println!("{:?}", disk.kind());
39    /// }
40    /// ```
41    fn kind(&self) -> DiskKind;
42
43    /// Returns the disk name.
44    ///
45    /// ```no_run
46    /// use sysinfo::{DiskExt, System, SystemExt};
47    ///
48    /// let mut s = System::new();
49    /// s.refresh_disks_list();
50    /// for disk in s.disks() {
51    ///     println!("{:?}", disk.name());
52    /// }
53    /// ```
54    fn name(&self) -> &OsStr;
55
56    /// Returns the file system used on this disk (so for example: `EXT4`, `NTFS`, etc...).
57    ///
58    /// ```no_run
59    /// use sysinfo::{DiskExt, System, SystemExt};
60    ///
61    /// let mut s = System::new();
62    /// s.refresh_disks_list();
63    /// for disk in s.disks() {
64    ///     println!("{:?}", disk.file_system());
65    /// }
66    /// ```
67    fn file_system(&self) -> &[u8];
68
69    /// Returns the mount point of the disk (`/` for example).
70    ///
71    /// ```no_run
72    /// use sysinfo::{DiskExt, System, SystemExt};
73    ///
74    /// let mut s = System::new();
75    /// s.refresh_disks_list();
76    /// for disk in s.disks() {
77    ///     println!("{:?}", disk.mount_point());
78    /// }
79    /// ```
80    fn mount_point(&self) -> &Path;
81
82    /// Returns the total disk size, in bytes.
83    ///
84    /// ```no_run
85    /// use sysinfo::{DiskExt, System, SystemExt};
86    ///
87    /// let mut s = System::new();
88    /// s.refresh_disks_list();
89    /// for disk in s.disks() {
90    ///     println!("{}", disk.total_space());
91    /// }
92    /// ```
93    fn total_space(&self) -> u64;
94
95    /// Returns the available disk size, in bytes.
96    ///
97    /// ```no_run
98    /// use sysinfo::{DiskExt, System, SystemExt};
99    ///
100    /// let mut s = System::new();
101    /// s.refresh_disks_list();
102    /// for disk in s.disks() {
103    ///     println!("{}", disk.available_space());
104    /// }
105    /// ```
106    fn available_space(&self) -> u64;
107
108    /// Returns `true` if the disk is removable.
109    ///
110    /// ```no_run
111    /// use sysinfo::{DiskExt, System, SystemExt};
112    ///
113    /// let mut s = System::new();
114    /// s.refresh_disks_list();
115    /// for disk in s.disks() {
116    ///     println!("{}", disk.is_removable());
117    /// }
118    /// ```
119    fn is_removable(&self) -> bool;
120
121    /// Updates the disk' information.
122    ///
123    /// ```no_run
124    /// use sysinfo::{DiskExt, System, SystemExt};
125    ///
126    /// let mut s = System::new();
127    /// s.refresh_disks_list();
128    /// for disk in s.disks_mut() {
129    ///     disk.refresh();
130    /// }
131    /// ```
132    fn refresh(&mut self) -> bool;
133}
134
135/// Contains all the methods of the [`Process`][crate::Process] struct.
136pub trait ProcessExt: Debug {
137    /// Sends [`Signal::Kill`] to the process (which is the only signal supported on all supported
138    /// platforms by this crate).
139    ///
140    /// If you want to send another signal, take a look at [`ProcessExt::kill_with`].
141    ///
142    /// To get the list of the supported signals on this system, use
143    /// [`SystemExt::SUPPORTED_SIGNALS`].
144    ///
145    /// ```no_run
146    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
147    ///
148    /// let s = System::new_all();
149    /// if let Some(process) = s.process(Pid::from(1337)) {
150    ///     process.kill();
151    /// }
152    /// ```
153    fn kill(&self) -> bool {
154        self.kill_with(Signal::Kill).unwrap_or(false)
155    }
156
157    /// Sends the given `signal` to the process. If the signal doesn't exist on this platform,
158    /// it'll do nothing and will return `None`. Otherwise it'll return if the signal was sent
159    /// successfully.
160    ///
161    /// If you just want to kill the process, use [`ProcessExt::kill`] directly.
162    ///
163    /// To get the list of the supported signals on this system, use
164    /// [`SystemExt::SUPPORTED_SIGNALS`].
165    ///
166    /// ```no_run
167    /// use sysinfo::{Pid, ProcessExt, Signal, System, SystemExt};
168    ///
169    /// let s = System::new_all();
170    /// if let Some(process) = s.process(Pid::from(1337)) {
171    ///     if process.kill_with(Signal::Kill).is_none() {
172    ///         eprintln!("This signal isn't supported on this platform");
173    ///     }
174    /// }
175    /// ```
176    fn kill_with(&self, signal: Signal) -> Option<bool>;
177
178    /// Returns the name of the process.
179    ///
180    /// **⚠️ Important ⚠️**
181    ///
182    /// On **Linux**, there are two things to know about processes' name:
183    ///  1. It is limited to 15 characters.
184    ///  2. It is not always the exe name.
185    ///
186    /// If you are looking for a specific process, unless you know what you are doing, in most
187    /// cases it's better to use [`ProcessExt::exe`] instead (which can be empty sometimes!).
188    ///
189    /// ```no_run
190    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
191    ///
192    /// let s = System::new_all();
193    /// if let Some(process) = s.process(Pid::from(1337)) {
194    ///     println!("{}", process.name());
195    /// }
196    /// ```
197    fn name(&self) -> &str;
198
199    /// Returns the command line.
200    ///
201    /// ```no_run
202    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
203    ///
204    /// let s = System::new_all();
205    /// if let Some(process) = s.process(Pid::from(1337)) {
206    ///     println!("{:?}", process.cmd());
207    /// }
208    /// ```
209    fn cmd(&self) -> &[String];
210
211    /// Returns the path to the process.
212    ///
213    /// ```no_run
214    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
215    ///
216    /// let s = System::new_all();
217    /// if let Some(process) = s.process(Pid::from(1337)) {
218    ///     println!("{}", process.exe().display());
219    /// }
220    /// ```
221    ///
222    /// ### Implementation notes
223    ///
224    /// On Linux, this method will return an empty path if there
225    /// was an error trying to read `/proc/<pid>/exe`. This can
226    /// happen, for example, if the permission levels or UID namespaces
227    /// between the caller and target processes are different.
228    ///
229    /// It is also the case that `cmd[0]` is _not_ usually a correct
230    /// replacement for this.
231    /// A process [may change its `cmd[0]` value](https://man7.org/linux/man-pages/man5/proc.5.html)
232    /// freely, making this an untrustworthy source of information.
233    fn exe(&self) -> &Path;
234
235    /// Returns the PID of the process.
236    ///
237    /// ```no_run
238    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
239    ///
240    /// let s = System::new_all();
241    /// if let Some(process) = s.process(Pid::from(1337)) {
242    ///     println!("{}", process.pid());
243    /// }
244    /// ```
245    fn pid(&self) -> Pid;
246
247    /// Returns the environment variables of the process.
248    ///
249    /// ```no_run
250    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
251    ///
252    /// let s = System::new_all();
253    /// if let Some(process) = s.process(Pid::from(1337)) {
254    ///     println!("{:?}", process.environ());
255    /// }
256    /// ```
257    fn environ(&self) -> &[String];
258
259    /// Returns the current working directory.
260    ///
261    /// ```no_run
262    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
263    ///
264    /// let s = System::new_all();
265    /// if let Some(process) = s.process(Pid::from(1337)) {
266    ///     println!("{}", process.cwd().display());
267    /// }
268    /// ```
269    fn cwd(&self) -> &Path;
270
271    /// Returns the path of the root directory.
272    ///
273    /// ```no_run
274    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
275    ///
276    /// let s = System::new_all();
277    /// if let Some(process) = s.process(Pid::from(1337)) {
278    ///     println!("{}", process.root().display());
279    /// }
280    /// ```
281    fn root(&self) -> &Path;
282
283    /// Returns the memory usage (in bytes).
284    ///
285    /// ```no_run
286    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
287    ///
288    /// let s = System::new_all();
289    /// if let Some(process) = s.process(Pid::from(1337)) {
290    ///     println!("{} bytes", process.memory());
291    /// }
292    /// ```
293    fn memory(&self) -> u64;
294
295    /// Returns the virtual memory usage (in bytes).
296    ///
297    /// ```no_run
298    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
299    ///
300    /// let s = System::new_all();
301    /// if let Some(process) = s.process(Pid::from(1337)) {
302    ///     println!("{} bytes", process.virtual_memory());
303    /// }
304    /// ```
305    fn virtual_memory(&self) -> u64;
306
307    /// Returns the parent PID.
308    ///
309    /// ```no_run
310    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
311    ///
312    /// let s = System::new_all();
313    /// if let Some(process) = s.process(Pid::from(1337)) {
314    ///     println!("{:?}", process.parent());
315    /// }
316    /// ```
317    fn parent(&self) -> Option<Pid>;
318
319    /// Returns the status of the process.
320    ///
321    /// ```no_run
322    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
323    ///
324    /// let s = System::new_all();
325    /// if let Some(process) = s.process(Pid::from(1337)) {
326    ///     println!("{:?}", process.status());
327    /// }
328    /// ```
329    fn status(&self) -> ProcessStatus;
330
331    /// Returns the time where the process was started (in seconds) from epoch.
332    ///
333    /// ```no_run
334    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
335    ///
336    /// let s = System::new_all();
337    /// if let Some(process) = s.process(Pid::from(1337)) {
338    ///     println!("Started at {} seconds", process.start_time());
339    /// }
340    /// ```
341    fn start_time(&self) -> u64;
342
343    /// Returns for how much time the process has been running (in seconds).
344    ///
345    /// ```no_run
346    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
347    ///
348    /// let s = System::new_all();
349    /// if let Some(process) = s.process(Pid::from(1337)) {
350    ///     println!("Running since {} seconds", process.run_time());
351    /// }
352    /// ```
353    fn run_time(&self) -> u64;
354
355    /// Returns the total CPU usage (in %). Notice that it might be bigger than 100 if run on a
356    /// multi-core machine.
357    ///
358    /// If you want a value between 0% and 100%, divide the returned value by the number of CPUs.
359    ///
360    /// ⚠️ To start to have accurate CPU usage, a process needs to be refreshed **twice** because
361    /// CPU usage computation is based on time diff (process time on a given time period divided by
362    /// total system time on the same time period).
363    ///
364    /// ⚠️ If you want accurate CPU usage number, better leave a bit of time
365    /// between two calls of this method (take a look at
366    /// [`SystemExt::MINIMUM_CPU_UPDATE_INTERVAL`] for more information).
367    ///
368    /// ```no_run
369    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
370    ///
371    /// let s = System::new_all();
372    /// if let Some(process) = s.process(Pid::from(1337)) {
373    ///     println!("{}%", process.cpu_usage());
374    /// }
375    /// ```
376    fn cpu_usage(&self) -> f32;
377
378    /// Returns number of bytes read and written to disk.
379    ///
380    /// ⚠️ On Windows and FreeBSD, this method actually returns **ALL** I/O read and written bytes.
381    ///
382    /// ```no_run
383    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
384    ///
385    /// let s = System::new_all();
386    /// if let Some(process) = s.process(Pid::from(1337)) {
387    ///     let disk_usage = process.disk_usage();
388    ///     println!("read bytes   : new/total => {}/{}",
389    ///         disk_usage.read_bytes,
390    ///         disk_usage.total_read_bytes,
391    ///     );
392    ///     println!("written bytes: new/total => {}/{}",
393    ///         disk_usage.written_bytes,
394    ///         disk_usage.total_written_bytes,
395    ///     );
396    /// }
397    /// ```
398    fn disk_usage(&self) -> DiskUsage;
399
400    /// Returns the ID of the owner user of this process or `None` if this information couldn't
401    /// be retrieved. If you want to get the [`User`] from it, take a look at
402    /// [`SystemExt::get_user_by_id`].
403    ///
404    /// ```no_run
405    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
406    ///
407    /// let mut s = System::new_all();
408    ///
409    /// if let Some(process) = s.process(Pid::from(1337)) {
410    ///     eprintln!("User id for process 1337: {:?}", process.user_id());
411    /// }
412    /// ```
413    fn user_id(&self) -> Option<&Uid>;
414
415    /// Returns the user ID of the effective owner of this process or `None` if this information
416    /// couldn't be retrieved. If you want to get the [`User`] from it, take a look at
417    /// [`SystemExt::get_user_by_id`].
418    ///
419    /// If you run something with `sudo`, the real user ID of the launched process will be the ID of
420    /// the user you are logged in as but effective user ID will be `0` (i-e root).
421    ///
422    /// ⚠️ It always returns `None` on Windows.
423    ///
424    /// ```no_run
425    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
426    ///
427    /// let mut s = System::new_all();
428    ///
429    /// if let Some(process) = s.process(Pid::from(1337)) {
430    ///     eprintln!("User id for process 1337: {:?}", process.effective_user_id());
431    /// }
432    /// ```
433    fn effective_user_id(&self) -> Option<&Uid>;
434
435    /// Returns the process group ID of the process.
436    ///
437    /// ⚠️ It always returns `None` on Windows.
438    ///
439    /// ```no_run
440    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
441    ///
442    /// let mut s = System::new_all();
443    ///
444    /// if let Some(process) = s.process(Pid::from(1337)) {
445    ///     eprintln!("Group ID for process 1337: {:?}", process.group_id());
446    /// }
447    /// ```
448    fn group_id(&self) -> Option<Gid>;
449
450    /// Returns the effective group ID of the process.
451    ///
452    /// If you run something with `sudo`, the real group ID of the launched process will be the
453    /// primary group ID you are logged in as but effective group ID will be `0` (i-e root).
454    ///
455    /// ⚠️ It always returns `None` on Windows.
456    ///
457    /// ```no_run
458    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
459    ///
460    /// let mut s = System::new_all();
461    ///
462    /// if let Some(process) = s.process(Pid::from(1337)) {
463    ///     eprintln!("User id for process 1337: {:?}", process.effective_group_id());
464    /// }
465    /// ```
466    fn effective_group_id(&self) -> Option<Gid>;
467
468    /// Wait for process termination.
469    ///
470    /// ```no_run
471    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
472    ///
473    /// let mut s = System::new_all();
474    ///
475    /// if let Some(process) = s.process(Pid::from(1337)) {
476    ///     eprintln!("Waiting for pid 1337");
477    ///     process.wait();
478    ///     eprintln!("Pid 1337 exited");
479    /// }
480    /// ```
481    fn wait(&self);
482
483    /// Returns the session ID for the current process or `None` if it couldn't be retrieved.
484    ///
485    /// ⚠️ This information is computed every time this method is called.
486    ///
487    /// ```no_run
488    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
489    ///
490    /// let mut s = System::new_all();
491    ///
492    /// if let Some(process) = s.process(Pid::from(1337)) {
493    ///     eprintln!("Session ID for process 1337: {:?}", process.session_id());
494    /// }
495    /// ```
496    fn session_id(&self) -> Option<Pid>;
497}
498
499/// Contains all the methods of the [`Cpu`][crate::Cpu] struct.
500pub trait CpuExt: Debug {
501    /// Returns this CPU's usage.
502    ///
503    /// Note: You'll need to refresh it at least twice (diff between the first and the second is
504    /// how CPU usage is computed) at first if you want to have a non-zero value.
505    ///
506    /// ```no_run
507    /// use sysinfo::{CpuExt, System, SystemExt, RefreshKind, CpuRefreshKind};
508    ///
509    /// let s = System::new_with_specifics(
510    ///     RefreshKind::new().with_cpu(CpuRefreshKind::everything()),
511    /// );
512    /// for cpu in s.cpus() {
513    ///     println!("{}%", cpu.cpu_usage());
514    /// }
515    /// ```
516    fn cpu_usage(&self) -> f32;
517
518    /// Returns this CPU's name.
519    ///
520    /// ```no_run
521    /// use sysinfo::{CpuExt, System, SystemExt, RefreshKind, CpuRefreshKind};
522    ///
523    /// let s = System::new_with_specifics(
524    ///     RefreshKind::new().with_cpu(CpuRefreshKind::everything()),
525    /// );
526    /// for cpu in s.cpus() {
527    ///     println!("{}", cpu.name());
528    /// }
529    /// ```
530    fn name(&self) -> &str;
531
532    /// Returns the CPU's vendor id.
533    ///
534    /// ```no_run
535    /// use sysinfo::{CpuExt, System, SystemExt, RefreshKind, CpuRefreshKind};
536    ///
537    /// let s = System::new_with_specifics(
538    ///     RefreshKind::new().with_cpu(CpuRefreshKind::everything()),
539    /// );
540    /// for cpu in s.cpus() {
541    ///     println!("{}", cpu.vendor_id());
542    /// }
543    /// ```
544    fn vendor_id(&self) -> &str;
545
546    /// Returns the CPU's brand.
547    ///
548    /// ```no_run
549    /// use sysinfo::{CpuExt, System, SystemExt, RefreshKind, CpuRefreshKind};
550    ///
551    /// let s = System::new_with_specifics(
552    ///     RefreshKind::new().with_cpu(CpuRefreshKind::everything()),
553    /// );
554    /// for cpu in s.cpus() {
555    ///     println!("{}", cpu.brand());
556    /// }
557    /// ```
558    fn brand(&self) -> &str;
559
560    /// Returns the CPU's frequency.
561    ///
562    /// ```no_run
563    /// use sysinfo::{CpuExt, System, SystemExt, RefreshKind, CpuRefreshKind};
564    ///
565    /// let s = System::new_with_specifics(
566    ///     RefreshKind::new().with_cpu(CpuRefreshKind::everything()),
567    /// );
568    /// for cpu in s.cpus() {
569    ///     println!("{}", cpu.frequency());
570    /// }
571    /// ```
572    fn frequency(&self) -> u64;
573}
574
575/// Contains all the methods of the [`System`][crate::System] type.
576pub trait SystemExt: Sized + Debug + Default + Send + Sync {
577    /// Returns `true` if this OS is supported. Please refer to the
578    /// [crate-level documentation](index.html) to get the list of supported OSes.
579    ///
580    /// ```
581    /// use sysinfo::{System, SystemExt};
582    ///
583    /// if System::IS_SUPPORTED {
584    ///     println!("This OS is supported!");
585    /// } else {
586    ///     println!("This OS isn't supported (yet?).");
587    /// }
588    /// ```
589    const IS_SUPPORTED: bool;
590
591    /// Returns the list of the supported signals on this system (used by
592    /// [`ProcessExt::kill_with`]).
593    ///
594    /// ```
595    /// use sysinfo::{System, SystemExt};
596    ///
597    /// println!("supported signals: {:?}", System::SUPPORTED_SIGNALS);
598    /// ```
599    const SUPPORTED_SIGNALS: &'static [Signal];
600
601    /// This is the minimum interval time used internally by `sysinfo` to refresh the CPU time.
602    ///
603    /// ⚠️ This value differs from one OS to another.
604    ///
605    /// Why is this constant even needed?
606    ///
607    /// If refreshed too often, the CPU usage of processes will be `0` whereas on Linux it'll
608    /// always be the maximum value (`number of CPUs * 100`).
609    const MINIMUM_CPU_UPDATE_INTERVAL: Duration;
610
611    /// Creates a new [`System`] instance with nothing loaded. If you want to
612    /// load components, network interfaces or the disks, you'll have to use the
613    /// `refresh_*_list` methods. [`SystemExt::refresh_networks_list`] for
614    /// example.
615    ///
616    /// Use the [`refresh_all`] method to update its internal information (or any of the `refresh_`
617    /// method).
618    ///
619    /// [`System`]: crate::System
620    /// [`refresh_all`]: #method.refresh_all
621    ///
622    /// ```no_run
623    /// use sysinfo::{System, SystemExt};
624    ///
625    /// let s = System::new();
626    /// ```
627    fn new() -> Self {
628        Self::new_with_specifics(RefreshKind::new())
629    }
630
631    /// Creates a new [`System`] instance with everything loaded.
632    ///
633    /// It is an equivalent of [`SystemExt::new_with_specifics`]`(`[`RefreshKind::everything`]`())`.
634    ///
635    /// [`System`]: crate::System
636    ///
637    /// ```no_run
638    /// use sysinfo::{System, SystemExt};
639    ///
640    /// let s = System::new_all();
641    /// ```
642    fn new_all() -> Self {
643        Self::new_with_specifics(RefreshKind::everything())
644    }
645
646    /// Creates a new [`System`] instance and refresh the data corresponding to the
647    /// given [`RefreshKind`].
648    ///
649    /// [`System`]: crate::System
650    ///
651    /// ```
652    /// use sysinfo::{RefreshKind, System, SystemExt};
653    ///
654    /// // We want everything except disks.
655    /// let mut system = System::new_with_specifics(
656    ///      RefreshKind::everything().without_disks_list(),
657    /// );
658    ///
659    /// assert!(system.disks().is_empty());
660    /// # if System::IS_SUPPORTED && !cfg!(feature = "apple-sandbox") {
661    /// assert!(!system.processes().is_empty());
662    /// # }
663    ///
664    /// // If you want the disks list afterwards, just call the corresponding
665    /// // "refresh_disks_list":
666    /// system.refresh_disks_list();
667    /// let disks = system.disks();
668    /// ```
669    fn new_with_specifics(refreshes: RefreshKind) -> Self;
670
671    /// Refreshes according to the given [`RefreshKind`]. It calls the corresponding
672    /// "refresh_" methods.
673    ///
674    /// ```
675    /// use sysinfo::{ProcessRefreshKind, RefreshKind, System, SystemExt};
676    ///
677    /// let mut s = System::new_all();
678    ///
679    /// // Let's just update networks and processes:
680    /// s.refresh_specifics(
681    ///     RefreshKind::new().with_networks().with_processes(ProcessRefreshKind::everything()),
682    /// );
683    /// ```
684    fn refresh_specifics(&mut self, refreshes: RefreshKind) {
685        if refreshes.memory() {
686            self.refresh_memory();
687        }
688        if let Some(kind) = refreshes.cpu() {
689            self.refresh_cpu_specifics(kind);
690        }
691        if refreshes.components_list() {
692            self.refresh_components_list();
693        } else if refreshes.components() {
694            self.refresh_components();
695        }
696        if refreshes.networks_list() {
697            self.refresh_networks_list();
698        } else if refreshes.networks() {
699            self.refresh_networks();
700        }
701        if let Some(kind) = refreshes.processes() {
702            self.refresh_processes_specifics(kind);
703        }
704        if refreshes.disks_list() {
705            self.refresh_disks_list();
706        } else if refreshes.disks() {
707            self.refresh_disks();
708        }
709        if refreshes.users_list() {
710            self.refresh_users_list();
711        }
712    }
713
714    /// Refreshes all system, processes, disks and network interfaces information.
715    ///
716    /// Please note that it doesn't recompute disks list, components list, network interfaces
717    /// list nor users list.
718    ///
719    /// ```no_run
720    /// use sysinfo::{System, SystemExt};
721    ///
722    /// let mut s = System::new_all();
723    /// s.refresh_all();
724    /// ```
725    fn refresh_all(&mut self) {
726        self.refresh_system();
727        self.refresh_processes();
728        self.refresh_disks();
729        self.refresh_networks();
730    }
731
732    /// Refreshes system information (RAM, swap, CPU usage and components' temperature).
733    ///
734    /// If you want some more specific refreshes, you might be interested into looking at
735    /// [`refresh_memory`], [`refresh_cpu`] and [`refresh_components`].
736    ///
737    /// [`refresh_memory`]: SystemExt::refresh_memory
738    /// [`refresh_cpu`]: SystemExt::refresh_memory
739    /// [`refresh_components`]: SystemExt::refresh_components
740    ///
741    /// ```no_run
742    /// use sysinfo::{System, SystemExt};
743    ///
744    /// let mut s = System::new_all();
745    /// s.refresh_system();
746    /// ```
747    fn refresh_system(&mut self) {
748        self.refresh_memory();
749        self.refresh_cpu();
750        self.refresh_components();
751    }
752
753    /// Refreshes RAM and SWAP usage.
754    ///
755    /// ```no_run
756    /// use sysinfo::{System, SystemExt};
757    ///
758    /// let mut s = System::new_all();
759    /// s.refresh_memory();
760    /// ```
761    fn refresh_memory(&mut self);
762
763    /// Refreshes CPUs information.
764    ///
765    /// ⚠️ Please note that the result will very likely be inaccurate at the first call.
766    /// You need to call this method at least twice (with a bit of time between each call, like
767    /// 200 ms, take a look at [`SystemExt::MINIMUM_CPU_UPDATE_INTERVAL`] for more information)
768    /// to get accurate value as it uses previous results to compute the next value.
769    ///
770    /// Calling this method is the same as calling
771    /// `refresh_cpu_specifics(CpuRefreshKind::new().with_cpu_usage())`.
772    ///
773    /// ```no_run
774    /// use sysinfo::{System, SystemExt};
775    ///
776    /// let mut s = System::new_all();
777    /// s.refresh_cpu();
778    /// ```
779    fn refresh_cpu(&mut self) {
780        self.refresh_cpu_specifics(CpuRefreshKind::new().with_cpu_usage())
781    }
782
783    /// Refreshes CPUs specific information.
784    ///
785    /// Please note that it doesn't recompute disks list, components list, network interfaces
786    /// list nor users list.
787    ///
788    /// ```no_run
789    /// use sysinfo::{System, SystemExt, CpuRefreshKind};
790    ///
791    /// let mut s = System::new_all();
792    /// s.refresh_cpu_specifics(CpuRefreshKind::everything());
793    /// ```
794    fn refresh_cpu_specifics(&mut self, refresh_kind: CpuRefreshKind);
795
796    /// Refreshes components' temperature.
797    ///
798    /// ```no_run
799    /// use sysinfo::{System, SystemExt};
800    ///
801    /// let mut s = System::new_all();
802    /// s.refresh_components();
803    /// ```
804    fn refresh_components(&mut self) {
805        for component in self.components_mut() {
806            component.refresh();
807        }
808    }
809
810    /// Refreshes components list.
811    ///
812    /// ```no_run
813    /// use sysinfo::{System, SystemExt};
814    ///
815    /// let mut s = System::new();
816    /// assert!(s.components().is_empty());
817    ///
818    /// s.refresh_components_list();
819    /// assert!(!s.components().is_empty());
820    /// ```
821    fn refresh_components_list(&mut self);
822
823    /// Gets all processes and updates their information.
824    ///
825    /// It does the same as `system.refresh_processes_specifics(ProcessRefreshKind::everything())`.
826    ///
827    /// ⚠️ On Linux, `sysinfo` keeps the `stat` files open by default. You can change this behaviour
828    /// by using [`set_open_files_limit`][crate::set_open_files_limit].
829    ///
830    /// ```no_run
831    /// use sysinfo::{System, SystemExt};
832    ///
833    /// let mut s = System::new_all();
834    /// s.refresh_processes();
835    /// ```
836    fn refresh_processes(&mut self) {
837        self.refresh_processes_specifics(ProcessRefreshKind::everything());
838    }
839
840    /// Gets all processes and updates the specified information.
841    ///
842    /// ⚠️ On Linux, `sysinfo` keeps the `stat` files open by default. You can change this behaviour
843    /// by using [`set_open_files_limit`][crate::set_open_files_limit].
844    ///
845    /// ```no_run
846    /// use sysinfo::{ProcessRefreshKind, System, SystemExt};
847    ///
848    /// let mut s = System::new_all();
849    /// s.refresh_processes_specifics(ProcessRefreshKind::new());
850    /// ```
851    fn refresh_processes_specifics(&mut self, refresh_kind: ProcessRefreshKind);
852
853    /// Refreshes *only* the process corresponding to `pid`. Returns `false` if the process doesn't
854    /// exist (it will **NOT** be removed from the processes if it doesn't exist anymore). If it
855    /// isn't listed yet, it'll be added.
856    ///
857    /// It is the same as calling
858    /// `sys.refresh_process_specifics(pid, ProcessRefreshKind::everything())`.
859    ///
860    /// ```no_run
861    /// use sysinfo::{Pid, System, SystemExt};
862    ///
863    /// let mut s = System::new_all();
864    /// s.refresh_process(Pid::from(1337));
865    /// ```
866    fn refresh_process(&mut self, pid: Pid) -> bool {
867        self.refresh_process_specifics(pid, ProcessRefreshKind::everything())
868    }
869
870    /// Refreshes *only* the process corresponding to `pid`. Returns `false` if the process doesn't
871    /// exist (it will **NOT** be removed from the processes if it doesn't exist anymore). If it
872    /// isn't listed yet, it'll be added.
873    ///
874    /// ```no_run
875    /// use sysinfo::{Pid, ProcessRefreshKind, System, SystemExt};
876    ///
877    /// let mut s = System::new_all();
878    /// s.refresh_process_specifics(Pid::from(1337), ProcessRefreshKind::new());
879    /// ```
880    fn refresh_process_specifics(&mut self, pid: Pid, refresh_kind: ProcessRefreshKind) -> bool;
881
882    /// Refreshes the listed disks' information.
883    ///
884    /// ```no_run
885    /// use sysinfo::{System, SystemExt};
886    ///
887    /// let mut s = System::new_all();
888    /// s.refresh_disks();
889    /// ```
890    fn refresh_disks(&mut self) {
891        for disk in self.disks_mut() {
892            disk.refresh();
893        }
894    }
895
896    /// The disk list will be emptied then completely recomputed.
897    ///
898    /// ## Linux
899    ///
900    /// ⚠️ On Linux, the [NFS](https://en.wikipedia.org/wiki/Network_File_System) file
901    /// systems are ignored and the information of a mounted NFS **cannot** be obtained
902    /// via [`SystemExt::refresh_disks_list`]. This is due to the fact that I/O function
903    /// `statvfs` used by [`SystemExt::refresh_disks_list`] is blocking and
904    /// [may hang](https://github.com/GuillaumeGomez/sysinfo/pull/876) in some cases,
905    /// requiring to call `systemctl stop` to terminate the NFS service from the remote
906    /// server in some cases.
907    ///
908    /// ```no_run
909    /// use sysinfo::{System, SystemExt};
910    ///
911    /// let mut s = System::new_all();
912    /// s.refresh_disks_list();
913    /// ```
914    fn refresh_disks_list(&mut self);
915
916    /// Refreshes users list.
917    ///
918    /// ```no_run
919    /// use sysinfo::{System, SystemExt};
920    ///
921    /// let mut s = System::new_all();
922    /// s.refresh_users_list();
923    /// ```
924    fn refresh_users_list(&mut self);
925
926    /// Refreshes networks data.
927    ///
928    /// ```no_run
929    /// use sysinfo::{System, SystemExt};
930    ///
931    /// let mut s = System::new_all();
932    /// s.refresh_networks();
933    /// ```
934    ///
935    /// It is a shortcut for:
936    ///
937    /// ```no_run
938    /// use sysinfo::{NetworksExt, System, SystemExt};
939    ///
940    /// let mut s = System::new_all();
941    /// let networks = s.networks_mut();
942    /// networks.refresh();
943    /// ```
944    fn refresh_networks(&mut self) {
945        self.networks_mut().refresh();
946    }
947
948    /// The network list will be updated: removing not existing anymore interfaces and adding new
949    /// ones.
950    ///
951    /// ```no_run
952    /// use sysinfo::{System, SystemExt};
953    ///
954    /// let mut s = System::new_all();
955    /// s.refresh_networks_list();
956    /// ```
957    ///
958    /// This is a shortcut for:
959    ///
960    /// ```no_run
961    /// use sysinfo::{NetworksExt, System, SystemExt};
962    ///
963    /// let mut s = System::new_all();
964    /// let networks = s.networks_mut();
965    /// networks.refresh_networks_list();
966    /// ```
967    fn refresh_networks_list(&mut self) {
968        self.networks_mut().refresh_networks_list();
969    }
970
971    /// Returns the process list.
972    ///
973    /// ```no_run
974    /// use sysinfo::{ProcessExt, System, SystemExt};
975    ///
976    /// let s = System::new_all();
977    /// for (pid, process) in s.processes() {
978    ///     println!("{} {}", pid, process.name());
979    /// }
980    /// ```
981    fn processes(&self) -> &HashMap<Pid, Process>;
982
983    /// Returns the process corresponding to the given `pid` or `None` if no such process exists.
984    ///
985    /// ```no_run
986    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
987    ///
988    /// let s = System::new_all();
989    /// if let Some(process) = s.process(Pid::from(1337)) {
990    ///     println!("{}", process.name());
991    /// }
992    /// ```
993    fn process(&self, pid: Pid) -> Option<&Process>;
994
995    /// Returns an iterator of process containing the given `name`.
996    ///
997    /// If you want only the processes with exactly the given `name`, take a look at
998    /// [`SystemExt::processes_by_exact_name`].
999    ///
1000    /// **⚠️ Important ⚠️**
1001    ///
1002    /// On **Linux**, there are two things to know about processes' name:
1003    ///  1. It is limited to 15 characters.
1004    ///  2. It is not always the exe name.
1005    ///
1006    /// ```no_run
1007    /// use sysinfo::{ProcessExt, System, SystemExt};
1008    ///
1009    /// let s = System::new_all();
1010    /// for process in s.processes_by_name("htop") {
1011    ///     println!("{} {}", process.pid(), process.name());
1012    /// }
1013    /// ```
1014    // FIXME: replace the returned type with `impl Iterator<Item = &Process>` when it's supported!
1015    fn processes_by_name<'a: 'b, 'b>(
1016        &'a self,
1017        name: &'b str,
1018    ) -> Box<dyn Iterator<Item = &'a Process> + 'b> {
1019        Box::new(
1020            self.processes()
1021                .values()
1022                .filter(move |val: &&Process| val.name().contains(name)),
1023        )
1024    }
1025
1026    /// Returns an iterator of processes with exactly the given `name`.
1027    ///
1028    /// If you instead want the processes containing `name`, take a look at
1029    /// [`SystemExt::processes_by_name`].
1030    ///
1031    /// **⚠️ Important ⚠️**
1032    ///
1033    /// On **Linux**, there are two things to know about processes' name:
1034    ///  1. It is limited to 15 characters.
1035    ///  2. It is not always the exe name.
1036    ///
1037    /// ```no_run
1038    /// use sysinfo::{ProcessExt, System, SystemExt};
1039    ///
1040    /// let s = System::new_all();
1041    /// for process in s.processes_by_exact_name("htop") {
1042    ///     println!("{} {}", process.pid(), process.name());
1043    /// }
1044    /// ```
1045    // FIXME: replace the returned type with `impl Iterator<Item = &Process>` when it's supported!
1046    fn processes_by_exact_name<'a: 'b, 'b>(
1047        &'a self,
1048        name: &'b str,
1049    ) -> Box<dyn Iterator<Item = &'a Process> + 'b> {
1050        Box::new(
1051            self.processes()
1052                .values()
1053                .filter(move |val: &&Process| val.name() == name),
1054        )
1055    }
1056
1057    /// Returns "global" CPUs information (aka the addition of all the CPUs).
1058    ///
1059    /// To have up-to-date information, you need to call [`SystemExt::refresh_cpu`] or
1060    /// [`SystemExt::refresh_specifics`] with `cpu` enabled.
1061    ///
1062    /// ```no_run
1063    /// use sysinfo::{CpuRefreshKind, CpuExt, RefreshKind, System, SystemExt};
1064    ///
1065    /// let s = System::new_with_specifics(
1066    ///     RefreshKind::new().with_cpu(CpuRefreshKind::everything()),
1067    /// );
1068    /// println!("{}%", s.global_cpu_info().cpu_usage());
1069    /// ```
1070    fn global_cpu_info(&self) -> &Cpu;
1071
1072    /// Returns the list of the CPUs.
1073    ///
1074    /// By default, the list of CPUs is empty until you call [`SystemExt::refresh_cpu`] or
1075    /// [`SystemExt::refresh_specifics`] with `cpu` enabled.
1076    ///
1077    /// ```no_run
1078    /// use sysinfo::{CpuRefreshKind, CpuExt, RefreshKind, System, SystemExt};
1079    ///
1080    /// let s = System::new_with_specifics(
1081    ///     RefreshKind::new().with_cpu(CpuRefreshKind::everything()),
1082    /// );
1083    /// for cpu in s.cpus() {
1084    ///     println!("{}%", cpu.cpu_usage());
1085    /// }
1086    /// ```
1087    fn cpus(&self) -> &[Cpu];
1088
1089    /// Returns the number of physical cores on the CPU or `None` if it couldn't get it.
1090    ///
1091    /// In case there are multiple CPUs, it will combine the physical core count of all the CPUs.
1092    ///
1093    /// **Important**: this information is computed every time this function is called.
1094    ///
1095    /// ```no_run
1096    /// use sysinfo::{CpuExt, System, SystemExt};
1097    ///
1098    /// let s = System::new();
1099    /// println!("{:?}", s.physical_core_count());
1100    /// ```
1101    fn physical_core_count(&self) -> Option<usize>;
1102
1103    /// Returns the RAM size in bytes.
1104    ///
1105    /// ```no_run
1106    /// use sysinfo::{System, SystemExt};
1107    ///
1108    /// let s = System::new_all();
1109    /// println!("{} bytes", s.total_memory());
1110    /// ```
1111    fn total_memory(&self) -> u64;
1112
1113    /// Returns the amount of free RAM in bytes.
1114    ///
1115    /// Generally, "free" memory refers to unallocated memory whereas "available" memory refers to
1116    /// memory that is available for (re)use.
1117    ///
1118    /// Side note: Windows doesn't report "free" memory so this method returns the same value
1119    /// as [`get_available_memory`](#tymethod.available_memory).
1120    ///
1121    /// ```no_run
1122    /// use sysinfo::{System, SystemExt};
1123    ///
1124    /// let s = System::new_all();
1125    /// println!("{} bytes", s.free_memory());
1126    /// ```
1127    fn free_memory(&self) -> u64;
1128
1129    /// Returns the amount of available RAM in bytes.
1130    ///
1131    /// Generally, "free" memory refers to unallocated memory whereas "available" memory refers to
1132    /// memory that is available for (re)use.
1133    ///
1134    /// ⚠️ Windows and FreeBSD don't report "available" memory so [`SystemExt::free_memory`]
1135    /// returns the same value as this method.
1136    ///
1137    /// ```no_run
1138    /// use sysinfo::{System, SystemExt};
1139    ///
1140    /// let s = System::new_all();
1141    /// println!("{} bytes", s.available_memory());
1142    /// ```
1143    fn available_memory(&self) -> u64;
1144
1145    /// Returns the amount of used RAM in bytes.
1146    ///
1147    /// ```no_run
1148    /// use sysinfo::{System, SystemExt};
1149    ///
1150    /// let s = System::new_all();
1151    /// println!("{} bytes", s.used_memory());
1152    /// ```
1153    fn used_memory(&self) -> u64;
1154
1155    /// Returns the SWAP size in bytes.
1156    ///
1157    /// ```no_run
1158    /// use sysinfo::{System, SystemExt};
1159    ///
1160    /// let s = System::new_all();
1161    /// println!("{} bytes", s.total_swap());
1162    /// ```
1163    fn total_swap(&self) -> u64;
1164
1165    /// Returns the amount of free SWAP in bytes.
1166    ///
1167    /// ```no_run
1168    /// use sysinfo::{System, SystemExt};
1169    ///
1170    /// let s = System::new_all();
1171    /// println!("{} bytes", s.free_swap());
1172    /// ```
1173    fn free_swap(&self) -> u64;
1174
1175    /// Returns the amount of used SWAP in bytes.
1176    ///
1177    /// ```no_run
1178    /// use sysinfo::{System, SystemExt};
1179    ///
1180    /// let s = System::new_all();
1181    /// println!("{} bytes", s.used_swap());
1182    /// ```
1183    fn used_swap(&self) -> u64;
1184
1185    /// Returns the components list.
1186    ///
1187    /// ```no_run
1188    /// use sysinfo::{ComponentExt, System, SystemExt};
1189    ///
1190    /// let s = System::new_all();
1191    /// for component in s.components() {
1192    ///     println!("{}: {}°C", component.label(), component.temperature());
1193    /// }
1194    /// ```
1195    fn components(&self) -> &[Component];
1196
1197    /// Returns a mutable components list.
1198    ///
1199    /// ```no_run
1200    /// use sysinfo::{ComponentExt, System, SystemExt};
1201    ///
1202    /// let mut s = System::new_all();
1203    /// for component in s.components_mut() {
1204    ///     component.refresh();
1205    /// }
1206    /// ```
1207    fn components_mut(&mut self) -> &mut [Component];
1208
1209    /// Returns the users list.
1210    ///
1211    /// ```no_run
1212    /// use sysinfo::{System, SystemExt, UserExt};
1213    ///
1214    /// let mut s = System::new_all();
1215    /// for user in s.users() {
1216    ///     println!("{} is in {} groups", user.name(), user.groups().len());
1217    /// }
1218    /// ```
1219    fn users(&self) -> &[User];
1220
1221    /// Returns the disks list.
1222    ///
1223    /// ```no_run
1224    /// use sysinfo::{DiskExt, System, SystemExt};
1225    ///
1226    /// let mut s = System::new();
1227    /// s.refresh_disks_list();
1228    /// for disk in s.disks() {
1229    ///     println!("{:?}", disk.name());
1230    /// }
1231    /// ```
1232    fn disks(&self) -> &[Disk];
1233
1234    /// Returns the disks list.
1235    ///
1236    /// ```no_run
1237    /// use sysinfo::{DiskExt, System, SystemExt};
1238    ///
1239    /// let mut s = System::new_all();
1240    /// for disk in s.disks_mut() {
1241    ///     disk.refresh();
1242    /// }
1243    /// ```
1244    fn disks_mut(&mut self) -> &mut [Disk];
1245
1246    /// Sort the disk list with the provided callback.
1247    ///
1248    /// Internally, it is using the [`slice::sort_unstable_by`] function, so please refer to it
1249    /// for implementation details.
1250    ///
1251    /// ⚠️ If you use [`SystemExt::refresh_disks_list`], you need to use this method before using
1252    /// [`SystemExt::disks`] or [`SystemExt::disks_mut`] if you want them to be sorted.
1253    fn sort_disks_by<F>(&mut self, compare: F)
1254    where
1255        F: FnMut(&Disk, &Disk) -> std::cmp::Ordering;
1256
1257    /// Returns the network interfaces object.
1258    ///
1259    /// ```no_run
1260    /// use sysinfo::{NetworkExt, NetworksExt, System, SystemExt};
1261    ///
1262    /// let s = System::new_all();
1263    /// let networks = s.networks();
1264    /// for (interface_name, data) in networks {
1265    ///     println!(
1266    ///         "[{}] in: {}, out: {}",
1267    ///         interface_name,
1268    ///         data.received(),
1269    ///         data.transmitted(),
1270    ///     );
1271    /// }
1272    /// ```
1273    fn networks(&self) -> &Networks;
1274
1275    /// Returns a mutable access to network interfaces.
1276    ///
1277    /// ```no_run
1278    /// use sysinfo::{NetworkExt, NetworksExt, System, SystemExt};
1279    ///
1280    /// let mut s = System::new_all();
1281    /// let networks = s.networks_mut();
1282    /// networks.refresh_networks_list();
1283    /// ```
1284    fn networks_mut(&mut self) -> &mut Networks;
1285
1286    /// Returns system uptime (in seconds).
1287    ///
1288    /// ```no_run
1289    /// use sysinfo::{System, SystemExt};
1290    ///
1291    /// let s = System::new_all();
1292    /// println!("System running since {} seconds", s.uptime());
1293    /// ```
1294    fn uptime(&self) -> u64;
1295
1296    /// Returns the time (in seconds) when the system booted since UNIX epoch.
1297    ///
1298    /// ```no_run
1299    /// use sysinfo::{System, SystemExt};
1300    ///
1301    /// let s = System::new();
1302    /// println!("System booted at {} seconds", s.boot_time());
1303    /// ```
1304    fn boot_time(&self) -> u64;
1305
1306    /// Returns the system load average value.
1307    ///
1308    /// ```no_run
1309    /// use sysinfo::{System, SystemExt};
1310    ///
1311    /// let s = System::new_all();
1312    /// let load_avg = s.load_average();
1313    /// println!(
1314    ///     "one minute: {}%, five minutes: {}%, fifteen minutes: {}%",
1315    ///     load_avg.one,
1316    ///     load_avg.five,
1317    ///     load_avg.fifteen,
1318    /// );
1319    /// ```
1320    fn load_average(&self) -> LoadAvg;
1321
1322    /// Returns the system name.
1323    ///
1324    /// **Important**: this information is computed every time this function is called.
1325    ///
1326    /// ```no_run
1327    /// use sysinfo::{System, SystemExt};
1328    ///
1329    /// let s = System::new();
1330    /// println!("OS: {:?}", s.name());
1331    /// ```
1332    fn name(&self) -> Option<String>;
1333
1334    /// Returns the system's kernel version.
1335    ///
1336    /// **Important**: this information is computed every time this function is called.
1337    ///
1338    /// ```no_run
1339    /// use sysinfo::{System, SystemExt};
1340    ///
1341    /// let s = System::new();
1342    /// println!("kernel version: {:?}", s.kernel_version());
1343    /// ```
1344    fn kernel_version(&self) -> Option<String>;
1345
1346    /// Returns the system version (e.g. for MacOS this will return 11.1 rather than the kernel version).
1347    ///
1348    /// **Important**: this information is computed every time this function is called.
1349    ///
1350    /// ```no_run
1351    /// use sysinfo::{System, SystemExt};
1352    ///
1353    /// let s = System::new();
1354    /// println!("OS version: {:?}", s.os_version());
1355    /// ```
1356    fn os_version(&self) -> Option<String>;
1357
1358    /// Returns the system long os version (e.g "MacOS 11.2 BigSur").
1359    ///
1360    /// **Important**: this information is computed every time this function is called.
1361    ///
1362    /// ```no_run
1363    /// use sysinfo::{System, SystemExt};
1364    ///
1365    /// let s = System::new();
1366    /// println!("Long OS Version: {:?}", s.long_os_version());
1367    /// ```
1368    fn long_os_version(&self) -> Option<String>;
1369
1370    /// Returns the distribution id as defined by os-release,
1371    /// or [`std::env::consts::OS`].
1372    ///
1373    /// See also
1374    /// - <https://www.freedesktop.org/software/systemd/man/os-release.html#ID=>
1375    /// - <https://doc.rust-lang.org/std/env/consts/constant.OS.html>
1376    ///
1377    /// **Important**: this information is computed every time this function is called.
1378    ///
1379    /// ```no_run
1380    /// use sysinfo::{System, SystemExt};
1381    ///
1382    /// let s = System::new();
1383    /// println!("Distribution ID: {:?}", s.distribution_id());
1384    /// ```
1385    fn distribution_id(&self) -> String;
1386
1387    /// Returns the system hostname based off DNS
1388    ///
1389    /// **Important**: this information is computed every time this function is called.
1390    ///
1391    /// ```no_run
1392    /// use sysinfo::{System, SystemExt};
1393    ///
1394    /// let s = System::new();
1395    /// println!("Hostname: {:?}", s.host_name());
1396    /// ```
1397    fn host_name(&self) -> Option<String>;
1398
1399    /// Returns the [`User`] matching the given `user_id`.
1400    ///
1401    /// **Important**: The user list must be filled before using this method, otherwise it will
1402    /// always return `None` (through the `refresh_*` methods).
1403    ///
1404    /// It is a shorthand for:
1405    ///
1406    /// ```ignore
1407    /// let s = System::new_all();
1408    /// s.users().find(|user| user.id() == user_id);
1409    /// ```
1410    ///
1411    /// Full example:
1412    ///
1413    /// ```no_run
1414    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
1415    ///
1416    /// let mut s = System::new_all();
1417    ///
1418    /// if let Some(process) = s.process(Pid::from(1337)) {
1419    ///     if let Some(user_id) = process.user_id() {
1420    ///         eprintln!("User for process 1337: {:?}", s.get_user_by_id(user_id));
1421    ///     }
1422    /// }
1423    /// ```
1424    fn get_user_by_id(&self, user_id: &Uid) -> Option<&User> {
1425        self.users().iter().find(|user| user.id() == user_id)
1426    }
1427}
1428
1429/// Getting volume of received and transmitted data.
1430pub trait NetworkExt: Debug {
1431    /// Returns the number of received bytes since the last refresh.
1432    ///
1433    /// ```no_run
1434    /// use sysinfo::{NetworkExt, NetworksExt, System, SystemExt};
1435    ///
1436    /// let s = System::new_all();
1437    /// let networks = s.networks();
1438    /// for (interface_name, network) in networks {
1439    ///     println!("in: {} B", network.received());
1440    /// }
1441    /// ```
1442    fn received(&self) -> u64;
1443
1444    /// Returns the total number of received bytes.
1445    ///
1446    /// ```no_run
1447    /// use sysinfo::{NetworkExt, NetworksExt, System, SystemExt};
1448    ///
1449    /// let s = System::new_all();
1450    /// let networks = s.networks();
1451    /// for (interface_name, network) in networks {
1452    ///     println!("in: {} B", network.total_received());
1453    /// }
1454    /// ```
1455    fn total_received(&self) -> u64;
1456
1457    /// Returns the number of transmitted bytes since the last refresh.
1458    ///
1459    /// ```no_run
1460    /// use sysinfo::{NetworkExt, NetworksExt, System, SystemExt};
1461    ///
1462    /// let s = System::new_all();
1463    /// let networks = s.networks();
1464    /// for (interface_name, network) in networks {
1465    ///     println!("out: {} B", network.transmitted());
1466    /// }
1467    /// ```
1468    fn transmitted(&self) -> u64;
1469
1470    /// Returns the total number of transmitted bytes.
1471    ///
1472    /// ```no_run
1473    /// use sysinfo::{NetworkExt, NetworksExt, System, SystemExt};
1474    ///
1475    /// let s = System::new_all();
1476    /// let networks = s.networks();
1477    /// for (interface_name, network) in networks {
1478    ///     println!("out: {} B", network.total_transmitted());
1479    /// }
1480    /// ```
1481    fn total_transmitted(&self) -> u64;
1482
1483    /// Returns the number of incoming packets since the last refresh.
1484    ///
1485    /// ```no_run
1486    /// use sysinfo::{NetworkExt, NetworksExt, System, SystemExt};
1487    ///
1488    /// let s = System::new_all();
1489    /// let networks = s.networks();
1490    /// for (interface_name, network) in networks {
1491    ///     println!("in: {}", network.packets_received());
1492    /// }
1493    /// ```
1494    fn packets_received(&self) -> u64;
1495
1496    /// Returns the total number of incoming packets.
1497    ///
1498    /// ```no_run
1499    /// use sysinfo::{NetworkExt, NetworksExt, System, SystemExt};
1500    ///
1501    /// let s = System::new_all();
1502    /// let networks = s.networks();
1503    /// for (interface_name, network) in networks {
1504    ///     println!("in: {}", network.total_packets_received());
1505    /// }
1506    /// ```
1507    fn total_packets_received(&self) -> u64;
1508
1509    /// Returns the number of outcoming packets since the last refresh.
1510    ///
1511    /// ```no_run
1512    /// use sysinfo::{NetworkExt, NetworksExt, System, SystemExt};
1513    ///
1514    /// let s = System::new_all();
1515    /// let networks = s.networks();
1516    /// for (interface_name, network) in networks {
1517    ///     println!("out: {}", network.packets_transmitted());
1518    /// }
1519    /// ```
1520    fn packets_transmitted(&self) -> u64;
1521
1522    /// Returns the total number of outcoming packets.
1523    ///
1524    /// ```no_run
1525    /// use sysinfo::{NetworkExt, NetworksExt, System, SystemExt};
1526    ///
1527    /// let s = System::new_all();
1528    /// let networks = s.networks();
1529    /// for (interface_name, network) in networks {
1530    ///     println!("out: {}", network.total_packets_transmitted());
1531    /// }
1532    /// ```
1533    fn total_packets_transmitted(&self) -> u64;
1534
1535    /// Returns the number of incoming errors since the last refresh.
1536    ///
1537    /// ```no_run
1538    /// use sysinfo::{NetworkExt, NetworksExt, System, SystemExt};
1539    ///
1540    /// let s = System::new_all();
1541    /// let networks = s.networks();
1542    /// for (interface_name, network) in networks {
1543    ///     println!("in: {}", network.errors_on_received());
1544    /// }
1545    /// ```
1546    fn errors_on_received(&self) -> u64;
1547
1548    /// Returns the total number of incoming errors.
1549    ///
1550    /// ```no_run
1551    /// use sysinfo::{NetworkExt, NetworksExt, System, SystemExt};
1552    ///
1553    /// let s = System::new_all();
1554    /// let networks = s.networks();
1555    /// for (interface_name, network) in networks {
1556    ///     println!("in: {}", network.total_errors_on_received());
1557    /// }
1558    /// ```
1559    fn total_errors_on_received(&self) -> u64;
1560
1561    /// Returns the number of outcoming errors since the last refresh.
1562    ///
1563    /// ```no_run
1564    /// use sysinfo::{NetworkExt, NetworksExt, System, SystemExt};
1565    ///
1566    /// let s = System::new_all();
1567    /// let networks = s.networks();
1568    /// for (interface_name, network) in networks {
1569    ///     println!("out: {}", network.errors_on_transmitted());
1570    /// }
1571    /// ```
1572    fn errors_on_transmitted(&self) -> u64;
1573
1574    /// Returns the total number of outcoming errors.
1575    ///
1576    /// ```no_run
1577    /// use sysinfo::{NetworkExt, NetworksExt, System, SystemExt};
1578    ///
1579    /// let s = System::new_all();
1580    /// let networks = s.networks();
1581    /// for (interface_name, network) in networks {
1582    ///     println!("out: {}", network.total_errors_on_transmitted());
1583    /// }
1584    /// ```
1585    fn total_errors_on_transmitted(&self) -> u64;
1586
1587    /// Returns the MAC address associated to current interface.
1588    ///
1589    /// ```no_run
1590    /// use sysinfo::{NetworkExt, NetworksExt, System, SystemExt};
1591    ///
1592    /// let s = System::new_all();
1593    /// let networks = s.networks();
1594    /// for (interface_name, network) in networks {
1595    ///     println!("MAC address: {}", network.mac_address());
1596    /// }
1597    /// ```
1598    fn mac_address(&self) -> MacAddr;
1599}
1600
1601/// Interacting with network interfaces.
1602pub trait NetworksExt: Debug {
1603    /// Returns an iterator over the network interfaces.
1604    ///
1605    /// ```no_run
1606    /// use sysinfo::{NetworkExt, NetworksExt, System, SystemExt};
1607    ///
1608    /// let s = System::new_all();
1609    /// let networks = s.networks();
1610    /// for (interface_name, network) in networks {
1611    ///     println!("in: {} B", network.received());
1612    /// }
1613    /// ```
1614    fn iter(&self) -> NetworksIter;
1615
1616    /// Refreshes the network interfaces list.
1617    ///
1618    /// ```no_run
1619    /// use sysinfo::{NetworksExt, System, SystemExt};
1620    ///
1621    /// let mut s = System::new_all();
1622    /// let networks = s.networks_mut();
1623    /// networks.refresh_networks_list();
1624    /// ```
1625    fn refresh_networks_list(&mut self);
1626
1627    /// Refreshes the network interfaces' content.
1628    ///
1629    /// ```no_run
1630    /// use sysinfo::{NetworksExt, System, SystemExt};
1631    ///
1632    /// let mut s = System::new_all();
1633    /// let networks = s.networks_mut();
1634    /// networks.refresh();
1635    /// ```
1636    fn refresh(&mut self);
1637}
1638
1639/// Getting a component temperature information.
1640pub trait ComponentExt: Debug {
1641    /// Returns the temperature of the component (in celsius degree).
1642    ///
1643    /// ```no_run
1644    /// use sysinfo::{ComponentExt, System, SystemExt};
1645    ///
1646    /// let s = System::new_all();
1647    /// for component in s.components() {
1648    ///     println!("{}°C", component.temperature());
1649    /// }
1650    /// ```
1651    ///
1652    /// ## Linux
1653    ///
1654    /// Returns `f32::NAN` if it failed to retrieve it.
1655    fn temperature(&self) -> f32;
1656
1657    /// Returns the maximum temperature of the component (in celsius degree).
1658    ///
1659    /// Note: if `temperature` is higher than the current `max`,
1660    /// `max` value will be updated on refresh.
1661    ///
1662    /// ```no_run
1663    /// use sysinfo::{ComponentExt, System, SystemExt};
1664    ///
1665    /// let s = System::new_all();
1666    /// for component in s.components() {
1667    ///     println!("{}°C", component.max());
1668    /// }
1669    /// ```
1670    ///
1671    /// ## Linux
1672    ///
1673    /// May be computed by `sysinfo` from kernel.
1674    /// Returns `f32::NAN` if it failed to retrieve it.
1675    fn max(&self) -> f32;
1676
1677    /// Returns the highest temperature before the component halts (in celsius degree).
1678    ///
1679    /// ```no_run
1680    /// use sysinfo::{ComponentExt, System, SystemExt};
1681    ///
1682    /// let s = System::new_all();
1683    /// for component in s.components() {
1684    ///     println!("{:?}°C", component.critical());
1685    /// }
1686    /// ```
1687    ///
1688    /// ## Linux
1689    ///
1690    /// Critical threshold defined by chip or kernel.
1691    fn critical(&self) -> Option<f32>;
1692
1693    /// Returns the label of the component.
1694    ///
1695    /// ```no_run
1696    /// use sysinfo::{ComponentExt, System, SystemExt};
1697    ///
1698    /// let s = System::new_all();
1699    /// for component in s.components() {
1700    ///     println!("{}", component.label());
1701    /// }
1702    /// ```
1703    ///
1704    /// ## Linux
1705    ///
1706    /// Since components information is retrieved thanks to `hwmon`,
1707    /// the labels are generated as follows.
1708    /// Note: it may change and it was inspired by `sensors` own formatting.
1709    ///
1710    /// | name | label | device_model | id_sensor | Computed label by `sysinfo` |
1711    /// |---------|--------|------------|----------|----------------------|
1712    /// | ✓    | ✓    | ✓  | ✓ | `"{name} {label} {device_model} temp{id}"` |
1713    /// | ✓    | ✓    | ✗  | ✓ | `"{name} {label} {id}"` |
1714    /// | ✓    | ✗    | ✓  | ✓ | `"{name} {device_model}"` |
1715    /// | ✓    | ✗    | ✗  | ✓ | `"{name} temp{id}"` |
1716    fn label(&self) -> &str;
1717
1718    /// Refreshes component.
1719    ///
1720    /// ```no_run
1721    /// use sysinfo::{ComponentExt, System, SystemExt};
1722    ///
1723    /// let mut s = System::new_all();
1724    /// for component in s.components_mut() {
1725    ///     component.refresh();
1726    /// }
1727    /// ```
1728    fn refresh(&mut self);
1729}
1730
1731/// Getting information for a user.
1732///
1733/// It is returned from [`SystemExt::users`].
1734///
1735/// ```no_run
1736/// use sysinfo::{System, SystemExt, UserExt};
1737///
1738/// let mut s = System::new_all();
1739/// for user in s.users() {
1740///     println!("{} is in {} groups", user.name(), user.groups().len());
1741/// }
1742/// ```
1743pub trait UserExt: Debug {
1744    /// Return the user id of the user.
1745    ///
1746    /// ```no_run
1747    /// use sysinfo::{System, SystemExt, UserExt};
1748    ///
1749    /// let mut s = System::new_all();
1750    /// for user in s.users() {
1751    ///     println!("{:?}", *user.id());
1752    /// }
1753    /// ```
1754    fn id(&self) -> &Uid;
1755
1756    /// Return the group id of the user.
1757    ///
1758    /// *NOTE* - On Windows, this value defaults to 0.  Windows doesn't have a `username` specific group assigned to the user.
1759    /// They do however have unique [Security Identifiers](https://docs.microsoft.com/en-us/windows/win32/secauthz/security-identifiers)
1760    /// made up of various [Components](https://docs.microsoft.com/en-us/windows/win32/secauthz/sid-components).
1761    /// Pieces of the SID may be a candidate for this field, but it doesn't map well to a single group id.
1762    ///
1763    /// ```no_run
1764    /// use sysinfo::{System, SystemExt, UserExt};
1765    ///
1766    /// let mut s = System::new_all();
1767    /// for user in s.users() {
1768    ///     println!("{}", *user.group_id());
1769    /// }
1770    /// ```
1771    fn group_id(&self) -> Gid;
1772
1773    /// Returns the name of the user.
1774    ///
1775    /// ```no_run
1776    /// use sysinfo::{System, SystemExt, UserExt};
1777    ///
1778    /// let mut s = System::new_all();
1779    /// for user in s.users() {
1780    ///     println!("{}", user.name());
1781    /// }
1782    /// ```
1783    fn name(&self) -> &str;
1784
1785    /// Returns the groups of the user.
1786    ///
1787    /// ```no_run
1788    /// use sysinfo::{System, SystemExt, UserExt};
1789    ///
1790    /// let mut s = System::new_all();
1791    /// for user in s.users() {
1792    ///     println!("{} is in {:?}", user.name(), user.groups());
1793    /// }
1794    /// ```
1795    fn groups(&self) -> &[String];
1796}