blob: a27b2ca21d5412c9766f093cb43c99242893a904 [file] [log] [blame]
// Take a look at the license at the top of the repository in the LICENSE file.
use crate::{ComponentInner, ComponentsInner};
/// Interacting with components.
///
/// ```no_run
/// use sysinfo::Components;
///
/// let components = Components::new_with_refreshed_list();
/// for component in &components {
/// println!("{component:?}");
/// }
/// ```
pub struct Components {
pub(crate) inner: ComponentsInner,
}
impl Default for Components {
fn default() -> Self {
Self::new()
}
}
impl From<Components> for Vec<Component> {
fn from(components: Components) -> Self {
components.inner.into_vec()
}
}
impl From<Vec<Component>> for Components {
fn from(components: Vec<Component>) -> Self {
Self {
inner: ComponentsInner::from_vec(components),
}
}
}
impl std::ops::Deref for Components {
type Target = [Component];
fn deref(&self) -> &Self::Target {
self.list()
}
}
impl std::ops::DerefMut for Components {
fn deref_mut(&mut self) -> &mut Self::Target {
self.list_mut()
}
}
impl<'a> IntoIterator for &'a Components {
type Item = &'a Component;
type IntoIter = std::slice::Iter<'a, Component>;
fn into_iter(self) -> Self::IntoIter {
self.list().iter()
}
}
impl<'a> IntoIterator for &'a mut Components {
type Item = &'a mut Component;
type IntoIter = std::slice::IterMut<'a, Component>;
fn into_iter(self) -> Self::IntoIter {
self.list_mut().iter_mut()
}
}
impl Components {
/// Creates a new empty [`Components`][crate::Components] type.
///
/// If you want it to be filled directly, take a look at
/// [`Components::new_with_refreshed_list`].
///
/// ```no_run
/// use sysinfo::Components;
///
/// let mut components = Components::new();
/// components.refresh(false);
/// for component in &components {
/// println!("{component:?}");
/// }
/// ```
pub fn new() -> Self {
Self {
inner: ComponentsInner::new(),
}
}
/// Creates a new [`Components`][crate::Components] type with the components list
/// loaded.
///
/// ```no_run
/// use sysinfo::Components;
///
/// let mut components = Components::new_with_refreshed_list();
/// for component in components.list() {
/// println!("{component:?}");
/// }
/// ```
pub fn new_with_refreshed_list() -> Self {
let mut components = Self::new();
components.refresh(true);
components
}
/// Returns the components list.
///
/// ```no_run
/// use sysinfo::Components;
///
/// let components = Components::new_with_refreshed_list();
/// for component in components.list() {
/// println!("{component:?}");
/// }
/// ```
pub fn list(&self) -> &[Component] {
self.inner.list()
}
/// Returns the components list.
///
/// ```no_run
/// use sysinfo::Components;
///
/// let mut components = Components::new_with_refreshed_list();
/// for component in components.list_mut() {
/// component.refresh();
/// println!("{component:?}");
/// }
/// ```
pub fn list_mut(&mut self) -> &mut [Component] {
self.inner.list_mut()
}
/// Refreshes the components list.
///
/// ```no_run
/// use sysinfo::Components;
///
/// let mut components = Components::new_with_refreshed_list();
/// // We wait some time...?
/// components.refresh(false);
/// ```
pub fn refresh(&mut self, remove_not_listed_components: bool) {
self.inner.refresh();
if remove_not_listed_components {
// Remove interfaces which are gone.
self.inner.components.retain_mut(|c| {
if !c.inner.updated {
return false;
}
c.inner.updated = false;
true
});
}
}
}
/// Getting a component temperature information.
///
/// ```no_run
/// use sysinfo::Components;
///
/// let components = Components::new_with_refreshed_list();
/// for component in &components {
/// if let Some(temperature) = component.temperature() {
/// println!("{} {temperature}°C", component.label());
/// } else {
/// println!("{} (unknown temperature)", component.label());
/// }
/// }
/// ```
pub struct Component {
pub(crate) inner: ComponentInner,
}
impl Component {
/// Returns the temperature of the component (in celsius degree).
///
/// ## Linux
///
/// Returns `f32::NAN` if it failed to retrieve it.
///
/// ```no_run
/// use sysinfo::Components;
///
/// let components = Components::new_with_refreshed_list();
/// for component in &components {
/// if let Some(temperature) = component.temperature() {
/// println!("{temperature}°C");
/// }
/// }
/// ```
pub fn temperature(&self) -> Option<f32> {
self.inner.temperature()
}
/// Returns the maximum temperature of the component (in celsius degree).
///
/// Note: if `temperature` is higher than the current `max`,
/// `max` value will be updated on refresh.
///
/// ## Linux
///
/// May be computed by `sysinfo` from kernel.
/// Returns `f32::NAN` if it failed to retrieve it.
///
/// ```no_run
/// use sysinfo::Components;
///
/// let components = Components::new_with_refreshed_list();
/// for component in &components {
/// if let Some(max) = component.max() {
/// println!("{max}°C");
/// }
/// }
/// ```
pub fn max(&self) -> Option<f32> {
self.inner.max()
}
/// Returns the highest temperature before the component halts (in celsius degree).
///
/// ## Linux
///
/// Critical threshold defined by chip or kernel.
///
/// ```no_run
/// use sysinfo::Components;
///
/// let components = Components::new_with_refreshed_list();
/// for component in &components {
/// if let Some(critical) = component.critical() {
/// println!("{critical}°C");
/// }
/// }
/// ```
pub fn critical(&self) -> Option<f32> {
self.inner.critical()
}
/// Returns the label of the component.
///
/// ## Linux
///
/// Since components information is retrieved thanks to `hwmon`,
/// the labels are generated as follows.
/// Note: it may change and it was inspired by `sensors` own formatting.
///
/// | name | label | device_model | id_sensor | Computed label by `sysinfo` |
/// |---------|--------|------------|----------|----------------------|
/// | ✓ | ✓ | ✓ | ✓ | `"{name} {label} {device_model}"` |
/// | ✓ | ✓ | ✗ | ✓ | `"{name} {label}"` |
/// | ✓ | ✗ | ✓ | ✓ | `"{name} {device_model}"` |
/// | ✓ | ✗ | ✗ | ✓ | `"{name} temp{id}"` |
///
/// ```no_run
/// use sysinfo::Components;
///
/// let components = Components::new_with_refreshed_list();
/// for component in &components {
/// println!("{}", component.label());
/// }
/// ```
pub fn label(&self) -> &str {
self.inner.label()
}
/// Refreshes component.
///
/// ```no_run
/// use sysinfo::Components;
///
/// let mut components = Components::new_with_refreshed_list();
/// for component in components.iter_mut() {
/// component.refresh();
/// }
/// ```
pub fn refresh(&mut self) {
self.inner.refresh()
}
}
#[cfg(test)]
mod tests {
use crate::*;
#[test]
fn test_components_mac_m1() {
let mut components = Components::new();
components.refresh(false);
components.refresh(false);
}
}