Skip to content

Commit

Permalink
Add DiskRefreshKind
Browse files Browse the repository at this point in the history
  • Loading branch information
dlowe committed Nov 22, 2024
1 parent 88f9c4b commit 89a50df
Show file tree
Hide file tree
Showing 8 changed files with 305 additions and 119 deletions.
166 changes: 155 additions & 11 deletions src/common/disk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::fmt;
use std::path::Path;

use crate::DiskUsage;
use crate::common::system::impl_get_set;

/// Struct containing a disk information.
///
Expand Down Expand Up @@ -133,7 +134,9 @@ impl Disk {
self.inner.is_read_only()
}

/// Updates the disk' information.
/// Updates the disk' information with everything loaded.
///
/// Equivalent to [`Disk::refresh_specifics(DiskRefreshKind::everything())`].
///
/// ```no_run
/// use sysinfo::Disks;
Expand All @@ -144,7 +147,21 @@ impl Disk {
/// }
/// ```
pub fn refresh(&mut self) -> bool {
self.inner.refresh()
self.refresh_specifics(DiskRefreshKind::everything())
}

/// Updates the disk's information corresponding to the given [`DiskRefreshKind`].
///
/// ```no_run
/// use sysinfo::{Disks, DiskRefreshKind};
///
/// let mut disks = Disks::new_with_refreshed_list();
/// for disk in disks.list_mut() {
/// disk.refresh_specifics(DiskRefreshKind::new());
/// }
/// ```
pub fn refresh_specifics(&mut self, refreshes: DiskRefreshKind) -> bool {
self.inner.refresh_specifics(refreshes)
}

/// Returns number of bytes read and written by the disk
Expand Down Expand Up @@ -246,7 +263,8 @@ impl Disks {
}

/// Creates a new [`Disks`][crate::Disks] type with the disk list loaded.
/// It is a combination of [`Disks::new`] and [`Disks::refresh_list`].
///
/// Equivalent to [`Disks::new_with_refreshed_list_specifics(DiskRefreshKind::everything())`].
///
/// ```no_run
/// use sysinfo::Disks;
Expand All @@ -257,8 +275,24 @@ impl Disks {
/// }
/// ```
pub fn new_with_refreshed_list() -> Self {
Self::new_with_refreshed_list_specifics(DiskRefreshKind::everything())
}

/// Creates a new [`Disks`][crate::Disks] type with the disk list loaded
/// and refreshed according to the given [`DiskRefreshKind`]. It is a combination of
/// [`Disks::new`] and [`Disks::refresh_list_specifics`].
///
/// ```no_run
/// use sysinfo::Disks;
///
/// let mut disks = Disks::new_with_refreshed_list_specifics(DiskRefreshKind::new());
/// for disk in disks.list() {
/// println!("{disk:?}");
/// }
/// ```
pub fn new_with_refreshed_list_specifics(refreshes: DiskRefreshKind) -> Self {
let mut disks = Self::new();
disks.refresh_list();
disks.refresh_list_specifics(refreshes);
disks
}

Expand Down Expand Up @@ -293,6 +327,13 @@ impl Disks {

/// Refreshes the listed disks' information.
///
/// Equivalent to [`Disk::refresh_specifics(DiskRefreshKind::everything())`].
pub fn refresh(&mut self) {
self.refresh_specifics(DiskRefreshKind::everything());
}

/// Refreshes the listed disks' information according to the given [`DiskRefreshKind`].
///
/// ⚠️ If a disk is added or removed, this method won't take it into account. Use
/// [`Disks::refresh_list`] instead.
///
Expand All @@ -306,18 +347,33 @@ impl Disks {
/// // We wait some time...?
/// disks.refresh();
/// ```
pub fn refresh(&mut self) {
self.inner.refresh();
pub fn refresh_specifics(&mut self, refreshes: DiskRefreshKind) {
self.inner.refresh_specifics(refreshes);
}

/// The disk list will be emptied then completely recomputed.
///
/// Equivalent to [`Disks::refresh_list_specifics(DiskRefreshKind::everything())`].
///
/// ```no_run
/// use sysinfo::Disks;
///
/// let mut disks = Disks::new();
/// disks.refresh_list();
/// ```
pub fn refresh_list(&mut self) {
self.refresh_list_specifics(DiskRefreshKind::everything());
}

/// The disk list will be emptied then completely recomputed according to the given
/// [`DiskRefreshKind`].
///
/// ## 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 [`Disks::refresh_list`]. This is due to the fact that I/O function
/// `statvfs` used by [`Disks::refresh_list`] is blocking and
/// via [`Disks::refresh_list_specifics`]. This is due to the fact that I/O function
/// `statvfs` used by [`Disks::refresh_list_specifics`] 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.
Expand All @@ -326,10 +382,10 @@ impl Disks {
/// use sysinfo::Disks;
///
/// let mut disks = Disks::new();
/// disks.refresh_list();
/// disks.refresh_list_specifics(DiskRefreshKind::new());
/// ```
pub fn refresh_list(&mut self) {
self.inner.refresh_list();
pub fn refresh_list_specifics(&mut self, refreshes: DiskRefreshKind) {
self.inner.refresh_list_specifics(refreshes);
}
}

Expand Down Expand Up @@ -378,3 +434,91 @@ impl fmt::Display for DiskKind {
})
}
}

/// Used to determine what you want to refresh specifically on the [`Disk`] 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
/// extra computation.
///
/// ```
/// use sysinfo::{Disks, DiskRefreshKind};
///
/// let mut disks = Disks::new_with_refreshed_list_specifics(DiskRefreshKind::new());
///
/// for disk in disks.list() {
/// assert_eq!(disk.total_space(), 0);
/// }
/// ```
#[derive(Clone, Copy, Debug)]
pub struct DiskRefreshKind {
kind: bool,
total_space: bool,
available_space: bool,
is_removable: bool,
is_read_only: bool,
usage: bool,
}

impl Default for DiskRefreshKind {
fn default() -> Self {
Self {
kind: true,
total_space: false,
available_space: false,
is_removable: false,
is_read_only: false,
usage: false,
}
}
}

impl DiskRefreshKind {
/// Creates a new `DiskRefreshKind` with every refresh *except kind* set to false.
///
/// ```
/// use sysinfo::DiskRefreshKind;
///
/// let r = DiskRefreshKind::new();
///
/// assert_eq!(r.kind(), true);
/// assert_eq!(r.total_space(), false);
/// assert_eq!(r.available_space(), false);
/// assert_eq!(r.is_removable(), false);
/// assert_eq!(r.is_read_only(), false);
/// ```
pub fn new() -> Self {
Self::default()
}

/// Creates a new `DiskRefreshKind` with every refresh set to true.
///
/// ```
/// use sysinfo::DiskRefreshKind;
///
/// let r = DiskRefreshKind::everything();
///
/// assert_eq!(r.kind(), true);
/// assert_eq!(r.total_space(), true);
/// assert_eq!(r.available_space(), true);
/// assert_eq!(r.is_removable(), true);
/// assert_eq!(r.is_read_only(), true);
/// ```
pub fn everything() -> Self {
Self {
kind: true,
total_space: true,
available_space: true,
is_removable: true,
is_read_only: true,
usage: true,
}
}

impl_get_set!(DiskRefreshKind, kind, with_kind, without_kind);
impl_get_set!(DiskRefreshKind, total_space, with_total_space, without_total_space);
impl_get_set!(DiskRefreshKind, available_space, with_available_space, without_available_space);
impl_get_set!(DiskRefreshKind, is_removable, with_is_removable, without_is_removable);
impl_get_set!(DiskRefreshKind, is_read_only, with_is_read_only, without_is_read_only);
impl_get_set!(DiskRefreshKind, usage, with_usage, without_usage);
}
4 changes: 2 additions & 2 deletions src/common/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1697,7 +1697,6 @@ macro_rules! impl_get_set {
use sysinfo::", stringify!($ty_name), ";
let r = ", stringify!($ty_name), "::new();
assert_eq!(r.", stringify!($name), "(), false);
let r = r.with_", stringify!($name), "();
assert_eq!(r.", stringify!($name), "(), true);
Expand All @@ -1715,7 +1714,6 @@ assert_eq!(r.", stringify!($name), "(), false);
use sysinfo::", stringify!($ty_name), ";
let r = ", stringify!($ty_name), "::new();
assert_eq!(r.", stringify!($name), "(), false);
let r = r.with_", stringify!($name), "();
assert_eq!(r.", stringify!($name), "(), true);
Expand Down Expand Up @@ -1858,6 +1856,8 @@ assert_eq!(r.", stringify!($name), "().is_some(), false);
};
}

pub(crate) use impl_get_set;

/// This enum allows you to specify when you want the related information to be updated.
///
/// For example if you only want the [`Process::exe()`] information to be refreshed only if it's not
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ cfg_if! {
#[cfg(feature = "component")]
pub use crate::common::component::{Component, Components};
#[cfg(feature = "disk")]
pub use crate::common::disk::{Disk, DiskKind, Disks};
pub use crate::common::disk::{Disk, DiskKind, DiskRefreshKind, Disks};
#[cfg(feature = "network")]
pub use crate::common::network::{IpNetwork, MacAddr, NetworkData, Networks};
#[cfg(feature = "system")]
Expand Down
10 changes: 5 additions & 5 deletions src/unix/apple/disk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::{
},
DiskUsage,
};
use crate::{Disk, DiskKind};
use crate::{Disk, DiskKind, DiskRefreshKind};

use core_foundation_sys::array::CFArrayCreate;
use core_foundation_sys::base::kCFAllocatorDefault;
Expand Down Expand Up @@ -72,7 +72,7 @@ impl DiskInner {
self.is_read_only
}

pub(crate) fn refresh(&mut self) -> bool {
pub(crate) fn refresh_specifics(&mut self, _refreshes: DiskRefreshKind) -> bool {
#[cfg(target_os = "macos")]
let Some((read_bytes, written_bytes)) = self
.bsd_name
Expand Down Expand Up @@ -129,7 +129,7 @@ impl crate::DisksInner {
}
}

pub(crate) fn refresh_list(&mut self) {
pub(crate) fn refresh_list_specifics(&mut self, _refreshes: DiskRefreshKind) {
unsafe {
// SAFETY: We don't keep any Objective-C objects around because we
// don't make any direct Objective-C calls in this code.
Expand All @@ -139,9 +139,9 @@ impl crate::DisksInner {
}
}

pub(crate) fn refresh(&mut self) {
pub(crate) fn refresh_specifics(&mut self, refreshes: DiskRefreshKind) {
for disk in self.list_mut() {
disk.refresh();
disk.refresh_specifics(refreshes);
}
}

Expand Down
10 changes: 5 additions & 5 deletions src/unix/freebsd/disk.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Take a look at the license at the top of the repository in the LICENSE file.

use crate::{Disk, DiskKind, DiskUsage};
use crate::{Disk, DiskKind, DiskUsage, DiskRefreshKind};

use std::ffi::{OsStr, OsString};
use std::os::unix::ffi::OsStringExt;
Expand Down Expand Up @@ -52,7 +52,7 @@ impl DiskInner {
self.is_read_only
}

pub(crate) fn refresh(&mut self) -> bool {
pub(crate) fn refresh_specifics(&mut self, _refreshes: DiskRefreshKind) -> bool {
unsafe {
let mut vfs: libc::statvfs = std::mem::zeroed();
refresh_disk(self, &mut vfs)
Expand All @@ -72,7 +72,7 @@ impl crate::DisksInner {
}
}

pub(crate) fn refresh_list(&mut self) {
pub(crate) fn refresh_list_specifics(&mut self, _refreshes: DiskRefreshKind) {
unsafe { get_all_list(&mut self.disks) }
}

Expand All @@ -84,9 +84,9 @@ impl crate::DisksInner {
&mut self.disks
}

pub(crate) fn refresh(&mut self) {
pub(crate) fn refresh_specifics(&mut self, refreshes: DiskRefreshKind) {
for disk in self.list_mut() {
disk.refresh();
disk.refresh_specifics(refreshes);
}
}
}
Expand Down
Loading

0 comments on commit 89a50df

Please sign in to comment.