joularcore 0.2.0

Joular Core is a platform to measure power and energy across all systems, OSes and devices
Documentation
/*
 * Copyright (c) 2025-2026, Adel Noureddine.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the
 * GNU Lesser General Public License v3.0 only (LGPL-3.0-only)
 * which accompanies this distribution, and is available at
 * https://www.gnu.org/licenses/lgpl-3.0.en.html
 *
 * Author : Adel Noureddine
 */

//! Per-platform sensor backends.
//!
//! [`current`] is the whole public surface here: it hands back the backend for
//! the running system as a [`Platform`]. The backends themselves are internal,
//! because naming one would tie a caller to a single operating system — read
//! power through the [`crate::sensor`] traits instead, and implement them to add
//! a source of your own.

use crate::config::ElevationPolicy;
use crate::sensor::Platform;

mod cpu_usage;

// Only the RAPL-based backends difference energy counters.
#[cfg(any(target_os = "windows", all(target_os = "linux", not(feature = "sbc"))))]
mod counter;

#[cfg(all(target_os = "linux", not(feature = "sbc")))]
mod linux;

#[cfg(target_os = "windows")]
mod windows;

#[cfg(target_os = "macos")]
mod macos;

#[cfg(target_os = "macos")]
mod macos_parse;

#[cfg(all(target_os = "linux", feature = "sbc"))]
mod sbc;

#[cfg(all(target_os = "linux", feature = "sbc"))]
mod sbc_models;

#[cfg(target_os = "linux")]
mod procfs;

#[cfg(any(target_os = "windows", all(target_os = "linux", not(feature = "sbc"))))]
mod gpu;

// A build for a target with no backend would otherwise fail deep inside
// `JoularCoreMonitor::from_config` with "cannot find function `current`".
#[cfg(not(any(target_os = "linux", target_os = "windows", target_os = "macos")))]
compile_error!(
    "joularcore has no sensor backend for this target; it supports Linux, Windows and macOS"
);

/// The backend for the platform this build targets.
///
/// Backends never fail to construct: a sensor that cannot be read reports that
/// on each read instead, so a program keeps running with the measurements it
/// can get.
///
/// `elevation` says how far the backend may go to obtain privileged sensor
/// access. Only macOS acts on it, because `powermetrics` must run as root
/// there; with [`ElevationPolicy::Never`] — the default — an unprivileged
/// process reports CPU and GPU power as unavailable rather than prompting.
/// Every other backend accepts it and ignores it, so callers have one signature
/// to code against.
#[must_use]
pub fn current(elevation: ElevationPolicy) -> Box<dyn Platform> {
    // `ElevationPolicy` is `Copy`, so binding it here costs nothing and keeps
    // the backends that ignore it from tripping the unused-variable lint.
    let _ = elevation;

    #[cfg(all(target_os = "linux", not(feature = "sbc")))]
    return Box::new(linux::LinuxPlatform);

    #[cfg(all(target_os = "linux", feature = "sbc"))]
    return Box::new(sbc::SbcPlatform);

    #[cfg(target_os = "windows")]
    return Box::new(windows::WindowsPlatform);

    #[cfg(target_os = "macos")]
    return Box::new(macos::MacOsPlatform::new(elevation));
}