use std::path::Path;
use serde::Deserialize;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
#[serde(default)]
pub struct CrashreportSection {
pub enabled: bool,
}
impl Default for CrashreportSection {
fn default() -> Self {
Self { enabled: true }
}
}
#[derive(Debug, Default, Deserialize)]
struct PartialConfig {
#[serde(default)]
crashreport: Option<CrashreportSection>,
}
pub fn read_section(path: &Path) -> Result<Option<CrashreportSection>, ReadError> {
let raw = match std::fs::read_to_string(path) {
Ok(s) => s,
Err(e) if e.kind() == std::io::ErrorKind::NotFound => return Ok(None),
Err(e) => return Err(ReadError::Io(e.to_string())),
};
let parsed: PartialConfig =
toml::from_str(&raw).map_err(|e| ReadError::Parse(e.to_string()))?;
Ok(parsed.crashreport)
}
#[derive(Debug)]
pub enum ReadError {
Io(String),
Parse(String),
}
impl std::fmt::Display for ReadError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ReadError::Io(s) => write!(f, "config.toml read error: {s}"),
ReadError::Parse(s) => write!(f, "config.toml parse error: {s}"),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use tempfile::TempDir;
#[test]
fn test_read_section_missing_file_returns_none() {
let tmp = TempDir::new().unwrap();
let path = tmp.path().join("config.toml");
assert!(read_section(&path).unwrap().is_none());
}
#[test]
fn test_read_section_absent_returns_none() {
let tmp = TempDir::new().unwrap();
let path = tmp.path().join("config.toml");
std::fs::write(&path, "[other]\nkey = \"value\"\n").unwrap();
assert!(read_section(&path).unwrap().is_none());
}
#[test]
fn test_read_section_enabled_true() {
let tmp = TempDir::new().unwrap();
let path = tmp.path().join("config.toml");
std::fs::write(&path, "[crashreport]\nenabled = true\n").unwrap();
assert_eq!(
read_section(&path).unwrap(),
Some(CrashreportSection { enabled: true })
);
}
#[test]
fn test_read_section_enabled_false() {
let tmp = TempDir::new().unwrap();
let path = tmp.path().join("config.toml");
std::fs::write(&path, "[crashreport]\nenabled = false\n").unwrap();
assert_eq!(
read_section(&path).unwrap(),
Some(CrashreportSection { enabled: false })
);
}
#[test]
fn test_read_section_empty_section_defaults_to_enabled() {
let tmp = TempDir::new().unwrap();
let path = tmp.path().join("config.toml");
std::fs::write(&path, "[crashreport]\n").unwrap();
assert_eq!(
read_section(&path).unwrap(),
Some(CrashreportSection { enabled: true })
);
}
}