use anyhow::Result;
use serde::{Deserialize, Serialize};
use std::path::Path;
pub const DEFAULT_THRESHOLD_SINGLE_MB: u32 = 256;
pub const DEFAULT_THRESHOLD_MULTI_MB: u32 = 32;
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct GpuConfig {
pub device: String,
pub calibrated: String,
pub threshold_single_mb: u32,
pub threshold_multi_mb: u32,
pub gpu_enabled: bool,
}
impl GpuConfig {
pub fn load(path: &Path) -> Option<Self> {
let content = std::fs::read_to_string(path).ok()?;
toml::from_str(&content).ok()
}
pub fn save(&self, path: &Path) -> Result<()> {
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent)?;
}
let content = toml::to_string(self)?;
std::fs::write(path, content)?;
Ok(())
}
}
#[derive(Debug, PartialEq)]
pub enum GpuConfigState {
Skip,
UseThresholds { single_mb: u32, multi_mb: u32 },
NeedsCalibration,
}
impl GpuConfigState {
pub fn resolve(
config: Option<GpuConfig>,
adapter_name: Option<&str>,
_config_path: &Path,
) -> Self {
let Some(name) = adapter_name else {
return GpuConfigState::Skip;
};
match config {
None => GpuConfigState::NeedsCalibration,
Some(cfg) if cfg.device != name => GpuConfigState::NeedsCalibration,
Some(cfg) if !cfg.gpu_enabled => GpuConfigState::Skip,
Some(cfg) => GpuConfigState::UseThresholds {
single_mb: cfg.threshold_single_mb,
multi_mb: cfg.threshold_multi_mb,
},
}
}
pub fn resolve_no_calibrate(adapter_name: Option<&str>) -> Self {
if adapter_name.is_none() {
return GpuConfigState::Skip;
}
GpuConfigState::UseThresholds {
single_mb: DEFAULT_THRESHOLD_SINGLE_MB,
multi_mb: DEFAULT_THRESHOLD_MULTI_MB,
}
}
}