use serde::Deserialize;
use std::collections::HashMap;
use std::path::{Path, PathBuf};
#[derive(Debug, Clone, Copy, Default, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
pub enum BurnInPosition {
UpperLeft,
#[default]
UpperRight,
LowerLeft,
LowerRight,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(default)]
pub struct BurnInConfig {
pub enabled: bool,
pub font_path: Option<PathBuf>,
pub show_frame: bool,
pub show_key: bool,
pub show_description: bool,
pub position: BurnInPosition,
pub padding: u32,
pub font_size: f32,
}
impl Default for BurnInConfig {
fn default() -> Self {
Self {
enabled: false,
font_path: None,
show_frame: true,
show_key: false,
show_description: false,
position: BurnInPosition::UpperRight,
padding: 5,
font_size: 18.0,
}
}
}
impl BurnInConfig {
pub fn enabled() -> Self {
Self {
enabled: true,
..Default::default()
}
}
pub fn with_font(mut self, path: impl Into<PathBuf>) -> Self {
self.font_path = Some(path.into());
self
}
pub fn with_show_frame(mut self, show: bool) -> Self {
self.show_frame = show;
self
}
pub fn with_show_key(mut self, show: bool) -> Self {
self.show_key = show;
self
}
pub fn with_show_description(mut self, show: bool) -> Self {
self.show_description = show;
self
}
pub fn with_position(mut self, position: BurnInPosition) -> Self {
self.position = position;
self
}
pub fn with_padding(mut self, padding: u32) -> Self {
self.padding = padding;
self
}
pub fn with_font_size(mut self, size: f32) -> Self {
self.font_size = size;
self
}
}
#[derive(Debug, Clone, Deserialize)]
#[serde(default)]
pub struct ScreenshotConfig {
pub output_dir: PathBuf,
pub buffer_capacity: usize,
pub format: ImageFormat,
pub jpeg_quality: JpegQuality,
pub filename_pattern: String,
pub auto_save: bool,
#[serde(default)]
pub burn_in: BurnInConfig,
#[serde(default)]
pub keys: HashMap<String, KeyConfig>,
}
#[derive(Debug, Clone, Copy, Default, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum ImageFormat {
#[default]
Png,
Jpeg,
}
#[derive(Debug, Clone, Copy, Default, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum JpegQuality {
Max, #[default]
High, Medium, Low, }
impl JpegQuality {
pub fn as_u8(self) -> u8 {
match self {
Self::Max => 100,
Self::High => 90,
Self::Medium => 75,
Self::Low => 50,
}
}
}
#[derive(Debug, Clone, Deserialize, Default)]
#[serde(default)]
pub struct KeyConfig {
pub buffer_capacity: Option<usize>,
pub format: Option<ImageFormat>,
pub jpeg_quality: Option<JpegQuality>,
pub auto_save: Option<bool>,
pub burn_in: Option<BurnInConfig>,
}
impl ScreenshotConfig {
pub fn load() -> Self {
let path = Path::new("screenshots.toml");
if path.exists() {
match std::fs::read_to_string(path) {
Ok(content) => toml::from_str(&content).unwrap_or_default(),
Err(_) => Self::default(),
}
} else {
Self::default()
}
}
pub fn with_output_dir(mut self, path: impl Into<PathBuf>) -> Self {
self.output_dir = path.into();
self
}
pub fn with_buffer_capacity(mut self, capacity: usize) -> Self {
self.buffer_capacity = capacity;
self
}
pub fn with_format(mut self, format: ImageFormat) -> Self {
self.format = format;
self
}
pub fn with_jpeg_quality(mut self, quality: JpegQuality) -> Self {
self.jpeg_quality = quality;
self
}
pub fn with_auto_save(mut self, auto_save: bool) -> Self {
self.auto_save = auto_save;
self
}
pub fn with_filename_pattern(mut self, pattern: impl Into<String>) -> Self {
self.filename_pattern = pattern.into();
self
}
pub fn with_burn_in(mut self, burn_in: BurnInConfig) -> Self {
self.burn_in = burn_in;
self
}
}
impl Default for ScreenshotConfig {
fn default() -> Self {
Self {
output_dir: PathBuf::from(".screenshots"),
buffer_capacity: 10,
format: ImageFormat::Png,
jpeg_quality: JpegQuality::High,
filename_pattern: "{timestamp}_{key}_{description}".to_string(),
auto_save: true,
burn_in: BurnInConfig::default(),
keys: HashMap::new(),
}
}
}