Repository: GuillaumeGomez/sysinfo
Pull request #1066 (2023-09-16 13:31:03)

Extract `Disks` from `System`
Part of #1063.


Patch:
diff --git a/README.md b/README.md
index 327d6bf..1efde0c 100644
--- a/README.md
+++ b/README.md
@@ -34,7 +34,10 @@ You have an example into the `examples` folder. You can run it with `cargo run -
 Otherwise, here is a little code sample:
 
 ```rust
-use sysinfo::{NetworkExt, Networks, NetworksExt, ProcessExt, System, SystemExt};
+use sysinfo::{
+    Disks, DisksExt, NetworkExt, Networks, NetworksExt, ProcessExt, System,
+    SystemExt,
+};
 
 // Please note that we use "new_all" to ensure that all list of
 // components, network interfaces, disks and users are already
@@ -44,26 +47,6 @@ let mut sys = System::new_all();
 // First we update all information of our `System` struct.
 sys.refresh_all();
 
-// We display all disks' information:
-println!("=> disks:");
-for disk in sys.disks().iter() {
-    println!("{:?}", disk);
-}
-
-// Network interfaces name, data received and data transmitted:
-let mut networks = Networks::new();
-networks.refresh_list();
-println!("=> networks:");
-for (interface_name, data) in &networks {
-    println!("{}: {}/{} B", interface_name, data.received(), data.transmitted());
-}
-
-// Components temperature:
-println!("=> components:");
-for component in sys.components() {
-    println!("{:?}", component);
-}
-
 println!("=> system:");
 // RAM and swap information:
 println!("total memory: {} bytes", sys.total_memory());
@@ -84,6 +67,30 @@ println!("NB CPUs: {}", sys.cpus().len());
 for (pid, process) in sys.processes() {
     println!("[{}] {} {:?}", pid, process.name(), process.disk_usage());
 }
+
+// We display all disks' information:
+println!("=> disks:");
+let mut disks = Disks::new();
+// We refresh the disk list.
+disks.refresh_list();
+for disk in disks.disks() {
+    println!("{:?}", disk);
+}
+
+// Network interfaces name, data received and data transmitted:
+let mut networks = Networks::new();
+// We refresh the network interface list.
+networks.refresh_list();
+println!("=> networks:");
+for (interface_name, data) in &networks {
+    println!("{}: {}/{} B", interface_name, data.received(), data.transmitted());
+}
+
+// Components temperature:
+println!("=> components:");
+for component in sys.components() {
+    println!("{:?}", component);
+}
 ```
 
 Please remember that to have some up-to-date information, you need to call the equivalent
diff --git a/benches/basic.rs b/benches/basic.rs
index e4fedae..21517ea 100644
--- a/benches/basic.rs
+++ b/benches/basic.rs
@@ -3,7 +3,7 @@
 extern crate test;
 
 use sysinfo::get_current_pid;
-use sysinfo::{DiskExt, NetworksExt, SystemExt};
+use sysinfo::{DiskExt, DisksExt, NetworksExt, SystemExt};
 
 #[bench]
 fn bench_new(b: &mut test::Bencher) {
@@ -70,9 +70,10 @@ fn bench_refresh_process(b: &mut test::Bencher) {
 
 #[bench]
 fn bench_refresh_disk(b: &mut test::Bencher) {
-    let mut s = sysinfo::System::new_all();
+    let mut disks = sysinfo::Disks::new();
+    disks.refresh_list();
 
-    let disks = s.disks_mut();
+    let disks = disks.disks_mut();
     let disk = &mut disks[0];
     b.iter(move || {
         disk.refresh();
@@ -81,19 +82,21 @@ fn bench_refresh_disk(b: &mut test::Bencher) {
 
 #[bench]
 fn bench_refresh_disks(b: &mut test::Bencher) {
-    let mut s = sysinfo::System::new_all();
+    let mut disks = sysinfo::Disks::new();
+    disks.refresh_list();
 
     b.iter(move || {
-        s.refresh_disks();
+        disks.refresh();
     });
 }
 
 #[bench]
 fn bench_refresh_disks_list(b: &mut test::Bencher) {
-    let mut s = sysinfo::System::new();
+    let mut disks = sysinfo::Disks::new();
+    disks.refresh_list();
 
     b.iter(move || {
-        s.refresh_disks_list();
+        disks.refresh_list();
     });
 }
 
diff --git a/examples/simple.rs b/examples/simple.rs
index 2959684..deae70d 100644
--- a/examples/simple.rs
+++ b/examples/simple.rs
@@ -8,7 +8,8 @@ use std::io::{self, BufRead, Write};
 use std::str::FromStr;
 use sysinfo::Signal::*;
 use sysinfo::{
-    CpuExt, NetworkExt, Networks, NetworksExt, Pid, ProcessExt, Signal, System, SystemExt, UserExt,
+    CpuExt, Disks, DisksExt, NetworkExt, Networks, NetworksExt, Pid, ProcessExt, Signal, System,
+    SystemExt, UserExt,
 };
 
 const signals: &[Signal] = &[
@@ -141,12 +142,17 @@ fn print_help() {
     writeln!(&mut io::stdout(), "quit               : Exit the program");
 }
 
-fn interpret_input(input: &str, sys: &mut System, networks: &mut Networks) -> bool {
+fn interpret_input(
+    input: &str,
+    sys: &mut System,
+    networks: &mut Networks,
+    disks: &mut Disks,
+) -> bool {
     match input.trim() {
         "help" => print_help(),
         "refresh_disks" => {
             writeln!(&mut io::stdout(), "Refreshing disk list...");
-            sys.refresh_disks_list();
+            disks.refresh_list();
             writeln!(&mut io::stdout(), "Done.");
         }
         "refresh_users" => {
@@ -336,7 +342,7 @@ fn interpret_input(input: &str, sys: &mut System, networks: &mut Networks) -> bo
             }
         }
         "disks" => {
-            for disk in sys.disks().iter() {
+            for disk in disks.disks() {
                 writeln!(&mut io::stdout(), "{disk:?}");
             }
         }
@@ -434,7 +440,9 @@ fn main() {
     println!("Getting system information...");
     let mut t = System::new_all();
     let mut n = Networks::new();
+    let mut d = Disks::new();
     n.refresh_list();
+    d.refresh_list();
     println!("Done.");
     let t_stin = io::stdin();
     let mut stin = t_stin.lock();
@@ -456,6 +464,6 @@ fn main() {
         if (&input as &str).ends_with('\n') {
             input.pop();
         }
-        done = interpret_input(input.as_ref(), &mut t, &mut n);
+        done = interpret_input(input.as_ref(), &mut t, &mut n, &mut d);
     }
 }
diff --git a/src/c_interface.rs b/src/c_interface.rs
index 5f5fb19..6212583 100644
--- a/src/c_interface.rs
+++ b/src/c_interface.rs
@@ -1,7 +1,8 @@
 // Take a look at the license at the top of the repository in the LICENSE file.
 
 use crate::{
-    CpuExt, NetworkExt, Networks, NetworksExt, Pid, Process, ProcessExt, System, SystemExt,
+    CpuExt, Disks, DisksExt, NetworkExt, Networks, NetworksExt, Pid, Process, ProcessExt, System,
+    SystemExt,
 };
 use libc::{self, c_char, c_float, c_uint, c_void, pid_t, size_t};
 use std::borrow::BorrowMut;
@@ -15,8 +16,10 @@ pub type CProcess = *const c_void;
 pub type RString = *const c_char;
 /// Callback used by [`processes`][crate::System#method.processes].
 pub type ProcessLoop = extern "C" fn(pid: pid_t, process: CProcess, data: *mut c_void) -> bool;
-/// Equivalent of [`System`][crate::System] struct.
+/// Equivalent of [`Networks`][crate::Networks] struct.
 pub type CNetworks = *mut c_void;
+/// Equivalent of [`Disks`][crate::Disks] struct.
+pub type CDisks = *mut c_void;
 
 /// Equivalent of [`System::new()`][crate::System#method.new].
 #[no_mangle]
@@ -133,31 +136,47 @@ pub extern "C" fn sysinfo_refresh_process(system: CSystem, pid: pid_t) {
     }
 }
 
-/// Equivalent of [`System::refresh_disks()`][crate::System#method.refresh_disks].
+/// Equivalent of [`Disks::new()`][crate::Disks#method.new].
 #[no_mangle]
-pub extern "C" fn sysinfo_refresh_disks(system: CSystem) {
-    assert!(!system.is_null());
+pub extern "C" fn sysinfo_disks_init() -> CDisks {
+    let disks = Box::new(Disks::new());
+    Box::into_raw(disks) as CDisks
+}
+
+/// Equivalent of `Disks::drop()`. Important in C to cleanup memory.
+#[no_mangle]
+pub extern "C" fn sysinfo_disks_destroy(disks: CDisks) {
+    assert!(!disks.is_null());
     unsafe {
-        let mut system: Box<System> = Box::from_raw(system as *mut System);
+        drop(Box::from_raw(disks as *mut Disks));
+    }
+}
+
+/// Equivalent of [`Disks::refresh()`][crate::Disks#method.refresh].
+#[no_mangle]
+pub extern "C" fn sysinfo_disks_refresh(disks: CDisks) {
+    assert!(!disks.is_null());
+    unsafe {
+        let mut disks: Box<Disks> = Box::from_raw(disks as *mut Disks);
         {
-            let system: &mut System = system.borrow_mut();
-            system.refresh_disks();
+            let disks: &mut Disks = disks.borrow_mut();
+            disks.refresh();
         }
-        Box::into_raw(system);
+        Box::into_raw(disks);
     }
 }
 
-/// Equivalent of [`System::refresh_disks_list()`][crate::System#method.refresh_disks_list].
+/// Equivalent of [`Disks::refresh_list()`][crate::Disks#method.refresh_list].
 #[no_mangle]
-pub extern "C" fn sysinfo_refresh_disks_list(system: CSystem) {
-    assert!(!system.is_null());
+pub extern "C" fn sysinfo_disks_refresh_list(disks: CDisks) {
+    assert!(!disks.is_null());
     unsafe {
-        let mut system: Box<System> = Box::from_raw(system as *mut System);
+        let mut disks: Box<Disks> = Box::from_raw(disks as *mut Disks);
         {
-            let system: &mut System = system.borrow_mut();
-            system.refresh_disks_list();
+            let disks: &mut Disks = disks.borrow_mut();
+            disks.refresh_list();
         }
-        Box::into_raw(system);
+        Box::into_raw(disks);
     }
 }
 
diff --git a/src/common.rs b/src/common.rs
index 334cc22..d11a365 100644
--- a/src/common.rs
+++ b/src/common.rs
@@ -345,7 +345,7 @@ impl CpuRefreshKind {
     impl_get_set!(CpuRefreshKind, frequency, with_frequency, without_frequency);
 }
 
-/// Used to determine what you want to refresh specifically on the [`System`] type.
+/// Used to determine what you want to refresh specifically on the [`System`][crate::System] type.
 ///
 /// ⚠️ Just like all other refresh types, ruling out a refresh doesn't assure you that
 /// the information won't be retrieved if the information is accessible without needing
@@ -354,21 +354,17 @@ impl CpuRefreshKind {
 /// ```
 /// use sysinfo::{RefreshKind, System, SystemExt};
 ///
-/// // We want everything except disks.
-/// let mut system = System::new_with_specifics(RefreshKind::everything().without_disks_list());
+/// // We want everything except memory.
+/// let mut system = System::new_with_specifics(RefreshKind::everything().without_memory());
 ///
-/// assert_eq!(system.disks().len(), 0);
+/// assert_eq!(system.total_memory(), 0);
 /// # if System::IS_SUPPORTED && !cfg!(feature = "apple-sandbox") {
 /// assert!(system.processes().len() > 0);
 /// # }
 /// ```
-///
-/// [`System`]: crate::System
 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
 pub struct RefreshKind {
     processes: Option<ProcessRefreshKind>,
-    disks_list: bool,
-    disks: bool,
     memory: bool,
     cpu: Option<CpuRefreshKind>,
     components: bool,
@@ -385,8 +381,6 @@ impl RefreshKind {
     /// let r = RefreshKind::new();
     ///
     /// assert_eq!(r.processes().is_some(), false);
-    /// assert_eq!(r.disks_list(), false);
-    /// assert_eq!(r.disks(), false);
     /// assert_eq!(r.memory(), false);
     /// assert_eq!(r.cpu().is_some(), false);
     /// assert_eq!(r.components(), false);
@@ -405,8 +399,6 @@ impl RefreshKind {
     /// let r = RefreshKind::everything();
     ///
     /// assert_eq!(r.processes().is_some(), true);
-    /// assert_eq!(r.disks_list(), true);
-    /// assert_eq!(r.disks(), true);
     /// assert_eq!(r.memory(), true);
     /// assert_eq!(r.cpu().is_some(), true);
     /// assert_eq!(r.components(), true);
@@ -416,8 +408,6 @@ impl RefreshKind {
     pub fn everything() -> Self {
         Self {
             processes: Some(ProcessRefreshKind::everything()),
-            disks: true,
-            disks_list: true,
             memory: true,
             cpu: Some(CpuRefreshKind::everything()),
             components: true,
@@ -433,8 +423,6 @@ impl RefreshKind {
         without_processes,
         ProcessRefreshKind
     );
-    impl_get_set!(RefreshKind, disks, with_disks, without_disks);
-    impl_get_set!(RefreshKind, disks_list, with_disks_list, without_disks_list);
     impl_get_set!(RefreshKind, memory, with_memory, without_memory);
     impl_get_set!(RefreshKind, cpu, with_cpu, without_cpu, CpuRefreshKind);
     impl_get_set!(RefreshKind, components, with_components, without_components);
@@ -505,10 +493,11 @@ impl<'a> Iterator for NetworksIter<'a> {
 /// Disks interfaces.
 ///
 /// ```no_run
-/// use sysinfo::{DiskExt, System, SystemExt};
+/// use sysinfo::{Disks, DisksExt};
 ///
-/// let s = System::new_all();
-/// for disk in s.disks().iter() {
+/// let mut disks = Disks::new();
+/// disks.refresh_list();
+/// for disk in disks.disks() {
 ///     println!("{:?}", disk);
 /// }
 /// ```
@@ -516,14 +505,6 @@ pub struct Disks {
     pub(crate) disks: Vec<Disk>,
 }
 
-impl Disks {
-    pub(crate) fn new() -> Self {
-        Self {
-            disks: Vec::with_capacity(2),
-        }
-    }
-}
-
 impl std::ops::Deref for Disks {
     type Target = [Disk];
 
@@ -543,10 +524,11 @@ impl std::ops::DerefMut for Disks {
 /// This type is returned by [`DiskExt::kind`](`crate::DiskExt::kind`).
 ///
 /// ```no_run
-/// use sysinfo::{System, SystemExt, DiskExt};
+/// use sysinfo::{DiskExt, Disks, DisksExt};
 ///
-/// let system = System::new_all();
-/// for disk in system.disks().iter() {
+/// let mut disks = Disks::new();
+/// disks.refresh_list();
+/// for disk in disks.disks() {
 ///     println!("{:?}: {:?}", disk.name(), disk.kind());
 /// }
 /// ```
diff --git a/src/debug.rs b/src/debug.rs
index 7ffb1d1..ad43538 100644
--- a/src/debug.rs
+++ b/src/debug.rs
@@ -30,7 +30,6 @@ impl fmt::Debug for System {
             .field("free swap", &self.free_swap())
             .field("nb CPUs", &self.cpus().len())
             .field("nb processes", &self.processes().len())
-            .field("nb disks", &self.disks().len())
             .field("nb components", &self.components().len())
             .finish()
     }
diff --git a/src/serde.rs b/src/serde.rs
index 344b475..651325f 100644
--- a/src/serde.rs
+++ b/src/serde.rs
@@ -113,7 +113,6 @@ impl serde::Serialize for crate::System {
 
         state.serialize_field("components", &self.components())?;
         state.serialize_field("users", &self.users())?;
-        state.serialize_field("disks", &self.disks())?;
 
         state.serialize_field("uptime", &self.uptime())?;
         state.serialize_field("boot_time", &self.boot_time())?;
diff --git a/src/sysinfo.h b/src/sysinfo.h
index 53f4d37..9b638af 100644
--- a/src/sysinfo.h
+++ b/src/sysinfo.h
@@ -9,6 +9,7 @@ typedef void* CSystem;
 typedef const void* CProcess;
 typedef const char* RString;
 typedef void* CNetworks;
+typedef void* CDisks;
 
 CSystem     sysinfo_init(void);
 void        sysinfo_destroy(CSystem system);
@@ -24,8 +25,12 @@ void        sysinfo_refresh_processes(CSystem system);
 #ifdef __linux__
 void        sysinfo_refresh_process(CSystem system, pid_t pid);
 #endif
-void        sysinfo_refresh_disks(CSystem system);
-void        sysinfo_refresh_disk_list(CSystem system);
+
+
+CDisks      sysinfo_disks_init(void);
+void        sysinfo_disks_destroy(CDisks disks);
+void        sysinfo_disks_refresh(CDisks disks);
+void        sysinfo_disks_refresh_list(CDisks disks);
 
 size_t      sysinfo_total_memory(CSystem system);
 size_t      sysinfo_free_memory(CSystem system);
diff --git a/src/traits.rs b/src/traits.rs
index 463aee9..b9f5974 100644
--- a/src/traits.rs
+++ b/src/traits.rs
@@ -5,8 +5,8 @@ use crate::{
     sys::{Component, Cpu, Disk, Process},
 };
 use crate::{
-    CpuRefreshKind, DiskKind, DiskUsage, Disks, Group, LoadAvg, NetworksIter, Pid,
-    ProcessRefreshKind, ProcessStatus, RefreshKind, Signal, User,
+    CpuRefreshKind, DiskKind, DiskUsage, Group, LoadAvg, NetworksIter, Pid, ProcessRefreshKind,
+    ProcessStatus, RefreshKind, Signal, User,
 };
 
 use std::collections::HashMap;
@@ -18,11 +18,11 @@ use std::time::Duration;
 /// Contains all the methods of the [`Disk`][crate::Disk] struct.
 ///
 /// ```no_run
-/// use sysinfo::{DiskExt, System, SystemExt};
+/// use sysinfo::{DiskExt, Disks, DisksExt};
 ///
-/// let mut s = System::new();
-/// s.refresh_disks_list();
-/// for disk in s.disks().iter() {
+/// let mut disks = Disks::new();
+/// disks.refresh_list();
+/// for disk in disks.disks() {
 ///     println!("{:?}: {:?}", disk.name(), disk.kind());
 /// }
 /// ```
@@ -30,12 +30,12 @@ pub trait DiskExt: Debug {
     /// Returns the kind of disk.
     ///
     /// ```no_run
-    /// use sysinfo::{DiskExt, System, SystemExt};
+    /// use sysinfo::{DiskExt, Disks, DisksExt};
     ///
-    /// let mut s = System::new();
-    /// s.refresh_disks_list();
-    /// for disk in s.disks().iter() {
-    ///     println!("{:?}", disk.kind());
+    /// let mut disks = Disks::new();
+    /// disks.refresh_list();
+    /// for disk in disks.disks() {
+    ///     println!("[{:?}] {:?}", disk.name(), disk.kind());
     /// }
     /// ```
     fn kind(&self) -> DiskKind;
@@ -43,11 +43,11 @@ pub trait DiskExt: Debug {
     /// Returns the disk name.
     ///
     /// ```no_run
-    /// use sysinfo::{DiskExt, System, SystemExt};
+    /// use sysinfo::{DiskExt, Disks, DisksExt};
     ///
-    /// let mut s = System::new();
-    /// s.refresh_disks_list();
-    /// for disk in s.disks().iter() {
+    /// let mut disks = Disks::new();
+    /// disks.refresh_list();
+    /// for disk in disks.disks() {
     ///     println!("{:?}", disk.name());
     /// }
     /// ```
@@ -56,12 +56,12 @@ pub trait DiskExt: Debug {
     /// Returns the file system used on this disk (so for example: `EXT4`, `NTFS`, etc...).
     ///
     /// ```no_run
-    /// use sysinfo::{DiskExt, System, SystemExt};
+    /// use sysinfo::{DiskExt, Disks, DisksExt};
     ///
-    /// let mut s = System::new();
-    /// s.refresh_disks_list();
-    /// for disk in s.disks().iter() {
-    ///     println!("{:?}", disk.file_system());
+    /// let mut disks = Disks::new();
+    /// disks.refresh_list();
+    /// for disk in disks.disks() {
+    ///     println!("[{:?}] {:?}", disk.name(), disk.file_system());
     /// }
     /// ```
     fn file_system(&self) -> &[u8];
@@ -69,12 +69,12 @@ pub trait DiskExt: Debug {
     /// Returns the mount point of the disk (`/` for example).
     ///
     /// ```no_run
-    /// use sysinfo::{DiskExt, System, SystemExt};
+    /// use sysinfo::{DiskExt, Disks, DisksExt};
     ///
-    /// let mut s = System::new();
-    /// s.refresh_disks_list();
-    /// for disk in s.disks().iter() {
-    ///     println!("{:?}", disk.mount_point());
+    /// let mut disks = Disks::new();
+    /// disks.refresh_list();
+    /// for disk in disks.disks() {
+    ///     println!("[{:?}] {:?}", disk.name(), disk.mount_point());
     /// }
     /// ```
     fn mount_point(&self) -> &Path;
@@ -82,12 +82,12 @@ pub trait DiskExt: Debug {
     /// Returns the total disk size, in bytes.
     ///
     /// ```no_run
-    /// use sysinfo::{DiskExt, System, SystemExt};
+    /// use sysinfo::{DiskExt, Disks, DisksExt};
     ///
-    /// let mut s = System::new();
-    /// s.refresh_disks_list();
-    /// for disk in s.disks().iter() {
-    ///     println!("{}", disk.total_space());
+    /// let mut disks = Disks::new();
+    /// disks.refresh_list();
+    /// for disk in disks.disks() {
+    ///     println!("[{:?}] {}B", disk.name(), disk.total_space());
     /// }
     /// ```
     fn total_space(&self) -> u64;
@@ -95,12 +95,12 @@ pub trait DiskExt: Debug {
     /// Returns the available disk size, in bytes.
     ///
     /// ```no_run
-    /// use sysinfo::{DiskExt, System, SystemExt};
+    /// use sysinfo::{DiskExt, Disks, DisksExt};
     ///
-    /// let mut s = System::new();
-    /// s.refresh_disks_list();
-    /// for disk in s.disks().iter() {
-    ///     println!("{}", disk.available_space());
+    /// let mut disks = Disks::new();
+    /// disks.refresh_list();
+    /// for disk in disks.disks() {
+    ///     println!("[{:?}] {}B", disk.name(), disk.available_space());
     /// }
     /// ```
     fn available_space(&self) -> u64;
@@ -108,12 +108,12 @@ pub trait DiskExt: Debug {
     /// Returns `true` if the disk is removable.
     ///
     /// ```no_run
-    /// use sysinfo::{DiskExt, System, SystemExt};
+    /// use sysinfo::{DiskExt, Disks, DisksExt};
     ///
-    /// let mut s = System::new();
-    /// s.refresh_disks_list();
-    /// for disk in s.disks().iter() {
-    ///     println!("{}", disk.is_removable());
+    /// let mut disks = Disks::new();
+    /// disks.refresh_list();
+    /// for disk in disks.disks() {
+    ///     println!("[{:?}] {}", disk.name(), disk.is_removable());
     /// }
     /// ```
     fn is_removable(&self) -> bool;
@@ -121,11 +121,11 @@ pub trait DiskExt: Debug {
     /// Updates the disk' information.
     ///
     /// ```no_run
-    /// use sysinfo::{DiskExt, System, SystemExt};
+    /// use sysinfo::{DiskExt, Disks, DisksExt};
     ///
-    /// let mut s = System::new();
-    /// s.refresh_disks_list();
-    /// for disk in s.disks_mut().iter_mut() {
+    /// let mut disks = Disks::new();
+    /// disks.refresh_list();
+    /// for disk in disks.disks_mut() {
     ///     disk.refresh();
     /// }
     /// ```
@@ -608,9 +608,7 @@ pub trait SystemExt: Sized + Debug + Default + Send + Sync {
     /// always be the maximum value (`number of CPUs * 100`).
     const MINIMUM_CPU_UPDATE_INTERVAL: Duration;
 
-    /// Creates a new [`System`] instance with nothing loaded. If you want to
-    /// load components, network interfaces or the disks, you'll have to use the
-    /// `refresh_*_list` methods.
+    /// Creates a new [`System`] instance with nothing loaded.
     ///
     /// Use the [`refresh_all`] method to update its internal information (or any of the `refresh_`
     /// method).
@@ -648,22 +646,16 @@ pub trait SystemExt: Sized + Debug + Default + Send + Sync {
     /// [`System`]: crate::System
     ///
     /// ```
-    /// use sysinfo::{RefreshKind, System, SystemExt};
+    /// use sysinfo::{ProcessRefreshKind, RefreshKind, System, SystemExt};
     ///
-    /// // We want everything except disks.
+    /// // We want to only refresh processes.
     /// let mut system = System::new_with_specifics(
-    ///      RefreshKind::everything().without_disks_list(),
+    ///      RefreshKind::new().with_processes(ProcessRefreshKind::everything()),
     /// );
     ///
-    /// assert!(system.disks().is_empty());
     /// # if System::IS_SUPPORTED && !cfg!(feature = "apple-sandbox") {
     /// assert!(!system.processes().is_empty());
     /// # }
-    ///
-    /// // If you want the disks list afterwards, just call the corresponding
-    /// // "refresh_disks_list":
-    /// system.refresh_disks_list();
-    /// let disks = system.disks();
     /// ```
     fn new_with_specifics(refreshes: RefreshKind) -> Self;
 
@@ -695,20 +687,12 @@ pub trait SystemExt: Sized + Debug + Default + Send + Sync {
         if let Some(kind) = refreshes.processes() {
             self.refresh_processes_specifics(kind);
         }
-        if refreshes.disks_list() {
-            self.refresh_disks_list();
-        } else if refreshes.disks() {
-            self.refresh_disks();
-        }
         if refreshes.users_list() {
             self.refresh_users_list();
         }
     }
 
-    /// Refreshes all system, processes, disks and network interfaces information.
-    ///
-    /// Please note that it doesn't recompute disks list, components list, network interfaces
-    /// list nor users list.
+    /// Refreshes all system and processes information.
     ///
     /// ```no_run
     /// use sysinfo::{System, SystemExt};
@@ -719,7 +703,6 @@ pub trait SystemExt: Sized + Debug + Default + Send + Sync {
     fn refresh_all(&mut self) {
         self.refresh_system();
         self.refresh_processes();
-        self.refresh_disks();
     }
 
     /// Refreshes system information (RAM, swap, CPU usage and components' temperature).
@@ -810,9 +793,6 @@ pub trait SystemExt: Sized + Debug + Default + Send + Sync {
 
     /// Refreshes CPUs specific information.
     ///
-    /// Please note that it doesn't recompute disks list, components list, network interfaces
-    /// list nor users list.
-    ///
     /// ```no_run
     /// use sysinfo::{System, SystemExt, CpuRefreshKind};
     ///
@@ -907,40 +887,6 @@ pub trait SystemExt: Sized + Debug + Default + Send + Sync {
     /// ```
     fn refresh_process_specifics(&mut self, pid: Pid, refresh_kind: ProcessRefreshKind) -> bool;
 
-    /// Refreshes the listed disks' information.
-    ///
-    /// ```no_run
-    /// use sysinfo::{System, SystemExt};
-    ///
-    /// let mut s = System::new_all();
-    /// s.refresh_disks();
-    /// ```
-    fn refresh_disks(&mut self) {
-        self.disks_mut().refresh();
-    }
-
-    /// The disk list will be emptied then completely recomputed.
-    ///
-    /// ## Linux
-    ///
-    /// ⚠️ On Linux, the [NFS](https://en.wikipedia.org/wiki/Network_File_System) file
-    /// systems are ignored and the information of a mounted NFS **cannot** be obtained
-    /// via [`SystemExt::refresh_disks_list`]. This is due to the fact that I/O function
-    /// `statvfs` used by [`SystemExt::refresh_disks_list`] is blocking and
-    /// [may hang](https://github.com/GuillaumeGomez/sysinfo/pull/876) in some cases,
-    /// requiring to call `systemctl stop` to terminate the NFS service from the remote
-    /// server in some cases.
-    ///
-    /// ```no_run
-    /// use sysinfo::{System, SystemExt};
-    ///
-    /// let mut s = System::new_all();
-    /// s.refresh_disks_list();
-    /// ```
-    fn refresh_disks_list(&mut self) {
-        self.disks_mut().refresh_list();
-    }
-
     /// Refreshes users list.
     ///
     /// ```no_run
@@ -1201,45 +1147,6 @@ pub trait SystemExt: Sized + Debug + Default + Send + Sync {
     /// ```
     fn users(&self) -> &[User];
 
-    /// Returns the disks list.
-    ///
-    /// ```no_run
-    /// use sysinfo::{DiskExt, System, SystemExt};
-    ///
-    /// let mut s = System::new();
-    /// s.refresh_disks_list();
-    /// for disk in s.disks().iter() {
-    ///     println!("{:?}", disk.name());
-    /// }
-    /// ```
-    fn disks(&self) -> &Disks;
-
-    /// Returns the disks list.
-    ///
-    /// ```no_run
-    /// use sysinfo::{DiskExt, System, SystemExt};
-    ///
-    /// let mut s = System::new_all();
-    /// for disk in s.disks_mut().iter_mut() {
-    ///     disk.refresh();
-    /// }
-    /// ```
-    fn disks_mut(&mut self) -> &mut Disks;
-
-    /// Sort the disk list with the provided callback.
-    ///
-    /// Internally, it is using the [`slice::sort_unstable_by`] function, so please refer to it
-    /// for implementation details.
-    ///
-    /// ⚠️ If you use [`SystemExt::refresh_disks_list`], you need to use this method before using
-    /// [`SystemExt::disks`] or [`SystemExt::disks_mut`] if you want them to be sorted.
-    fn sort_disks_by<F>(&mut self, compare: F)
-    where
-        F: FnMut(&Disk, &Disk) -> std::cmp::Ordering,
-    {
-        self.disks_mut().sort_unstable_by(compare);
-    }
-
     /// Returns system uptime (in seconds).
     ///
     /// ```no_run
@@ -1614,14 +1521,28 @@ pub trait NetworksExt: Debug {
 
 /// Interacting with disks.
 pub trait DisksExt: Debug {
+    /// Creates a new `Disks` type.
+    ///
+    /// ```no_run
+    /// use sysinfo::{Disks, DisksExt};
+    ///
+    /// let mut disks = Disks::new();
+    /// disks.refresh_list();
+    /// for disk in disks.disks() {
+    ///     eprintln!("{disk:?}");
+    /// }
+    /// ```
+    fn new() -> Self;
+
     /// Returns the disks list.
     ///
     /// ```no_run
-    /// use sysinfo::{DiskExt, System, SystemExt};
+    /// use sysinfo::{Disks, DisksExt};
     ///
-    /// let s = System::new_all();
-    /// for disk in s.disks().iter() {
-    ///     println!("{:?}", disk.name());
+    /// let mut disks = Disks::new();
+    /// disks.refresh_list();
+    /// for disk in disks.disks() {
+    ///     eprintln!("{disk:?}");
     /// }
     /// ```
     fn disks(&self) -> &[Disk];
@@ -1629,11 +1550,13 @@ pub trait DisksExt: Debug {
     /// Returns the disks list.
     ///
     /// ```no_run
-    /// use sysinfo::{DiskExt, System, SystemExt};
+    /// use sysinfo::{DiskExt, Disks, DisksExt};
     ///
-    /// let mut s = System::new_all();
-    /// for disk in s.disks_mut().iter_mut() {
+    /// let mut disks = Disks::new();
+    /// disks.refresh_list();
+    /// for disk in disks.disks_mut() {
     ///     disk.refresh();
+    ///     eprintln!("{disk:?}");
     /// }
     /// ```
     fn disks_mut(&mut self) -> &mut [Disk];
@@ -1646,17 +1569,17 @@ pub trait DisksExt: Debug {
     /// You can do the same without this method by calling:
     ///
     /// ```no_run
-    /// use sysinfo::{DiskExt, DisksExt, System, SystemExt};
+    /// use sysinfo::{DiskExt, DisksExt, Disks};
     ///
-    /// let mut s = System::new_all();
-    /// let disks = s.disks_mut();
+    /// let mut disks = Disks::new();
+    /// disks.refresh_list();
     /// disks.sort_by(|disk1, disk2| {
     ///     disk1.name().partial_cmp(disk2.name()).unwrap()
     /// });
     /// ```
     ///
-    /// ⚠️ If you use [`SystemExt::refresh_disks_list`], you need to use this method before using
-    /// [`SystemExt::disks`] or [`SystemExt::disks_mut`] if you want them to be sorted again.
+    /// ⚠️ If you use [`DisksExt::refresh_list`], you will need to call this method to sort the
+    /// disks again.
     fn sort_by<F>(&mut self, compare: F)
     where
         F: FnMut(&Disk, &Disk) -> std::cmp::Ordering,
@@ -1666,11 +1589,17 @@ pub trait DisksExt: Debug {
 
     /// Refreshes the listed disks' information.
     ///
+    /// ⚠️ If you didn't call [`DisksExt::refresh_list`] beforehand, this method will do nothing as
+    /// the disk list will be empty.
+    ///
     /// ```no_run
-    /// use sysinfo::{DisksExt, System, SystemExt};
+    /// use sysinfo::{Disks, DisksExt};
     ///
-    /// let mut s = System::new_all();
-    /// s.disks_mut().refresh();
+    /// let mut disks = Disks::new();
+    /// // We get the disk list.
+    /// disks.refresh_list();
+    /// // We wait some time...?
+    /// disks.refresh();
     /// ```
     fn refresh(&mut self) {
         for disk in self.disks_mut() {
@@ -1684,17 +1613,17 @@ pub trait DisksExt: Debug {
     ///
     /// ⚠️ On Linux, the [NFS](https://en.wikipedia.org/wiki/Network_File_System) file
     /// systems are ignored and the information of a mounted NFS **cannot** be obtained
-    /// via [`SystemExt::refresh_disks_list`]. This is due to the fact that I/O function
-    /// `statvfs` used by [`SystemExt::refresh_disks_list`] is blocking and
+    /// via [`DisksExt::refresh_list`]. This is due to the fact that I/O function
+    /// `statvfs` used by [`DisksExt::refresh_list`] is blocking and
     /// [may hang](https://github.com/GuillaumeGomez/sysinfo/pull/876) in some cases,
     /// requiring to call `systemctl stop` to terminate the NFS service from the remote
     /// server in some cases.
     ///
     /// ```no_run
-    /// use sysinfo::{DisksExt, System, SystemExt};
+    /// use sysinfo::{Disks, DisksExt};
     ///
-    /// let mut s = System::new_all();
-    /// s.disks_mut().refresh_list();
+    /// let mut disks = Disks::new();
+    /// disks.refresh_list();
     /// ```
     fn refresh_list(&mut self);
 }
diff --git a/src/unix/apple/disk.rs b/src/unix/apple/disk.rs
index f9a81d7..bdf8158 100644
--- a/src/unix/apple/disk.rs
+++ b/src/unix/apple/disk.rs
@@ -82,6 +82,12 @@ impl DiskExt for Disk {
 }
 
 impl DisksExt for Disks {
+    fn new() -> Self {
+        Self {
+            disks: Vec::with_capacity(2),
+        }
+    }
+
     fn refresh_list(&mut self) {
         unsafe {
             get_disks(&mut self.disks);
diff --git a/src/unix/apple/system.rs b/src/unix/apple/system.rs
index 8801850..8596090 100644
--- a/src/unix/apple/system.rs
+++ b/src/unix/apple/system.rs
@@ -5,9 +5,7 @@ use crate::sys::cpu::*;
 use crate::sys::process::*;
 use crate::sys::utils::{get_sys_value, get_sys_value_by_name};
 
-use crate::{
-    CpuRefreshKind, Disks, LoadAvg, Pid, ProcessRefreshKind, RefreshKind, SystemExt, User,
-};
+use crate::{CpuRefreshKind, LoadAvg, Pid, ProcessRefreshKind, RefreshKind, SystemExt, User};
 
 #[cfg(all(target_os = "macos", not(feature = "apple-sandbox")))]
 use crate::ProcessExt;
@@ -86,7 +84,6 @@ pub struct System {
     page_size_b: u64,
     #[cfg(not(any(target_os = "ios", feature = "apple-sandbox")))]
     components: Components,
-    disks: Disks,
     port: mach_port_t,
     users: Vec<User>,
     boot_time: u64,
@@ -153,7 +150,6 @@ impl SystemExt for System {
                 page_size_b: sysconf(_SC_PAGESIZE) as _,
                 #[cfg(not(any(target_os = "ios", feature = "apple-sandbox")))]
                 components: Components::new(),
-                disks: Disks::new(),
                 port,
                 users: Vec::new(),
                 boot_time: boot_time(),
@@ -401,14 +397,6 @@ impl SystemExt for System {
         &mut []
     }
 
-    fn disks(&self) -> &Disks {
-        &self.disks
-    }
-
-    fn disks_mut(&mut self) -> &mut Disks {
-        &mut self.disks
-    }
-
     fn uptime(&self) -> u64 {
         unsafe {
             let csec = libc::time(::std::ptr::null_mut());
diff --git a/src/unix/freebsd/disk.rs b/src/unix/freebsd/disk.rs
index 1fcff2e..7c40a1e 100644
--- a/src/unix/freebsd/disk.rs
+++ b/src/unix/freebsd/disk.rs
@@ -56,6 +56,12 @@ impl DiskExt for Disk {
 }
 
 impl DisksExt for Disks {
+    fn new() -> Self {
+        Self {
+            disks: Vec::with_capacity(2),
+        }
+    }
+
     fn refresh_list(&mut self) {
         unsafe { get_all_disks(&mut self.disks) }
     }
diff --git a/src/unix/freebsd/system.rs b/src/unix/freebsd/system.rs
index 6c5ef5c..9533471 100644
--- a/src/unix/freebsd/system.rs
+++ b/src/unix/freebsd/system.rs
@@ -2,7 +2,7 @@
 
 use crate::{
     sys::{component::Component, Cpu, Process},
-    CpuRefreshKind, Disks, LoadAvg, Pid, ProcessRefreshKind, RefreshKind, SystemExt, User,
+    CpuRefreshKind, LoadAvg, Pid, ProcessRefreshKind, RefreshKind, SystemExt, User,
 };
 
 use std::cell::UnsafeCell;
@@ -65,7 +65,6 @@ pub struct System {
     swap_total: u64,
     swap_used: u64,
     components: Vec<Component>,
-    disks: Disks,
     users: Vec<User>,
     boot_time: u64,
     system_info: SystemInfo,
@@ -88,7 +87,6 @@ impl SystemExt for System {
             swap_total: 0,
             swap_used: 0,
             components: Vec::with_capacity(2),
-            disks: Disks::new(),
             users: Vec::new(),
             boot_time: boot_time(),
             system_info,
@@ -244,14 +242,6 @@ impl SystemExt for System {
         &mut self.components
     }
 
-    fn disks(&self) -> &Disks {
-        &self.disks
-    }
-
-    fn disks_mut(&mut self) -> &mut Disks {
-        &mut self.disks
-    }
-
     fn uptime(&self) -> u64 {
         unsafe {
             let csec = libc::time(::std::ptr::null_mut());
diff --git a/src/unix/linux/disk.rs b/src/unix/linux/disk.rs
index 7f840b0..bd2aabf 100644
--- a/src/unix/linux/disk.rs
+++ b/src/unix/linux/disk.rs
@@ -73,6 +73,12 @@ impl DiskExt for Disk {
 }
 
 impl DisksExt for Disks {
+    fn new() -> Self {
+        Self {
+            disks: Vec::with_capacity(2),
+        }
+    }
+
     fn refresh_list(&mut self) {
         get_all_disks(
             &mut self.disks,
diff --git a/src/unix/linux/system.rs b/src/unix/linux/system.rs
index a9f66e1..35497fb 100644
--- a/src/unix/linux/system.rs
+++ b/src/unix/linux/system.rs
@@ -4,9 +4,7 @@ use crate::sys::component::{self, Component};
 use crate::sys::cpu::*;
 use crate::sys::process::*;
 use crate::sys::utils::{get_all_data, to_u64};
-use crate::{
-    CpuRefreshKind, Disks, LoadAvg, Pid, ProcessRefreshKind, RefreshKind, SystemExt, User,
-};
+use crate::{CpuRefreshKind, LoadAvg, Pid, ProcessRefreshKind, RefreshKind, SystemExt, User};
 
 use libc::{self, c_char, c_int, sysconf, _SC_CLK_TCK, _SC_HOST_NAME_MAX, _SC_PAGESIZE};
 use std::cmp::min;
@@ -160,7 +158,6 @@ pub struct System {
     swap_total: u64,
     swap_free: u64,
     components: Vec<Component>,
-    disks: Disks,
     users: Vec<User>,
     info: SystemInfo,
     cpus: CpusWrapper,
@@ -234,7 +231,6 @@ impl SystemExt for System {
             swap_free: 0,
             cpus: CpusWrapper::new(),
             components: Vec::new(),
-            disks: Disks::new(),
             users: Vec::new(),
             info: SystemInfo::new(),
         };
@@ -438,14 +434,6 @@ impl SystemExt for System {
         &mut self.components
     }
 
-    fn disks(&self) -> &Disks {
-        &self.disks
-    }
-
-    fn disks_mut(&mut self) -> &mut Disks {
-        &mut self.disks
-    }
-
     fn uptime(&self) -> u64 {
         let content = get_all_data("/proc/uptime", 50).unwrap_or_default();
         content
diff --git a/src/unknown/disk.rs b/src/unknown/disk.rs
index cc3d56e..e38e38d 100644
--- a/src/unknown/disk.rs
+++ b/src/unknown/disk.rs
@@ -42,6 +42,10 @@ impl DiskExt for Disk {
 }
 
 impl DisksExt for Disks {
+    fn new() -> Self {
+        Self { disks: Vec::new() }
+    }
+
     fn refresh_list(&mut self) {
         // Does nothing.
     }
diff --git a/src/unknown/system.rs b/src/unknown/system.rs
index 5256654..1caefa8 100644
--- a/src/unknown/system.rs
+++ b/src/unknown/system.rs
@@ -2,7 +2,7 @@
 
 use crate::{
     sys::{component::Component, Cpu, Process},
-    CpuRefreshKind, Disks, LoadAvg, Pid, ProcessRefreshKind, RefreshKind, SystemExt, User,
+    CpuRefreshKind, LoadAvg, Pid, ProcessRefreshKind, RefreshKind, SystemExt, User,
 };
 
 use std::collections::HashMap;
@@ -17,7 +17,6 @@ declare_signals! {
 pub struct System {
     processes_list: HashMap<Pid, Process>,
     global_cpu: Cpu,
-    disks: Disks,
 }
 
 impl SystemExt for System {
@@ -29,7 +28,6 @@ impl SystemExt for System {
         System {
             processes_list: Default::default(),
             global_cpu: Cpu::new(),
-            disks: Disks::new(),
         }
     }
 
@@ -107,14 +105,6 @@ impl SystemExt for System {
         &mut []
     }
 
-    fn disks(&self) -> &Disks {
-        &self.disks
-    }
-
-    fn disks_mut(&mut self) -> &mut Disks {
-        &mut self.disks
-    }
-
     fn uptime(&self) -> u64 {
         0
     }
diff --git a/src/windows/disk.rs b/src/windows/disk.rs
index b68e2b9..65ae361 100644
--- a/src/windows/disk.rs
+++ b/src/windows/disk.rs
@@ -83,6 +83,12 @@ impl DiskExt for Disk {
 }
 
 impl DisksExt for Disks {
+    fn new() -> Self {
+        Self {
+            disks: Vec::with_capacity(2),
+        }
+    }
+
     fn refresh_list(&mut self) {
         unsafe {
             self.disks = get_disks();
diff --git a/src/windows/system.rs b/src/windows/system.rs
index 2fa388c..2dc5838 100644
--- a/src/windows/system.rs
+++ b/src/windows/system.rs
@@ -1,8 +1,7 @@
 // Take a look at the license at the top of the repository in the LICENSE file.
 
 use crate::{
-    CpuRefreshKind, Disks, LoadAvg, Pid, ProcessExt, ProcessRefreshKind, RefreshKind, SystemExt,
-    User,
+    CpuRefreshKind, LoadAvg, Pid, ProcessExt, ProcessRefreshKind, RefreshKind, SystemExt, User,
 };
 use winapi::um::winreg::HKEY_LOCAL_MACHINE;
 
@@ -51,7 +50,6 @@ pub struct System {
     swap_used: u64,
     cpus: CpusWrapper,
     components: Vec<Component>,
-    disks: Disks,
     query: Option<Query>,
     boot_time: u64,
     users: Vec<User>,
@@ -102,7 +100,6 @@ impl SystemExt for System {
             swap_used: 0,
             cpus: CpusWrapper::new(),
             components: Vec::new(),
-            disks: Disks::new(),
             query: None,
             boot_time: unsafe { boot_time() },
             users: Vec::new(),
@@ -412,14 +409,6 @@ impl SystemExt for System {
         &mut self.components
     }
 
-    fn disks(&self) -> &Disks {
-        &self.disks
-    }
-
-    fn disks_mut(&mut self) -> &mut Disks {
-        &mut self.disks
-    }
-
     fn users(&self) -> &[User] {
         &self.users
     }


Test patch:
diff --git a/tests/disk_list.rs b/tests/disk_list.rs
index 164d5b9..2d3ab1e 100644
--- a/tests/disk_list.rs
+++ b/tests/disk_list.rs
@@ -2,13 +2,15 @@
 
 #[test]
 fn test_disks() {
-    use sysinfo::SystemExt;
+    use sysinfo::{DisksExt, SystemExt};
 
     if sysinfo::System::IS_SUPPORTED {
         let s = sysinfo::System::new_all();
         // If we don't have any physical core present, it's very likely that we're inside a VM...
         if s.physical_core_count().unwrap_or_default() > 0 {
-            assert!(!s.disks().is_empty());
+            let mut disks = sysinfo::Disks::new();
+            disks.refresh_list();
+            assert!(!disks.disks().is_empty());
         }
     }
 }