docs: Added some code documentation

This commit is contained in:
Alexey 2026-05-08 12:33:56 +03:00
commit 4c2ddde26f
5 changed files with 70 additions and 20 deletions

View file

@ -2,10 +2,13 @@ use std::{collections::HashMap, hash::{DefaultHasher, Hash, Hasher}};
use serde::{Serialize, Deserialize};
use slint::Color;
/// Enum that is either an color or an alias
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
#[serde(untagged)]
pub enum ConfigColor {
/// ARGB color
Raw(u32),
/// Alias to a color defined in [Colors::aliases]
Alias(String),
}
@ -15,11 +18,16 @@ impl Default for ConfigColor {
}
}
/// Struct used for events colors
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
#[serde(default)]
pub struct EventColor {
/// Base color of the event
pub background: ConfigColor,
/// Color of the text inside the event
/// If none, color defaults to [Colors::text]
pub text: Option<ConfigColor>,
/// How often this color will be chosen for the event
pub priority: u64,
}
@ -33,16 +41,23 @@ impl Default for EventColor {
}
}
/// Colors used by Aliveline
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
#[serde(default)]
pub struct Colors {
/// Maps aliases to actual colors
pub aliases: HashMap<String, u32>,
/// Color behind the timeline
pub background: ConfigColor,
/// Color of the timeline itself
pub timeline: ConfigColor,
/// Color of the text on the timeline background
pub text: ConfigColor,
/// Color used to replace ill-defined aliases
/// If it is ill-defined itself, uses black color
pub fallback: ConfigColor,
/// List of event colors
/// Colors are chosen pseudorandomly by their priority
pub events: Vec<EventColor>,
}
@ -58,22 +73,30 @@ fn argb(value: u32) -> Color {
}
impl Colors {
/// Get [Colors::fallback] or the default color if it is also ill-defined
#[inline(always)]
pub fn fallback_color(&self) -> Color {
self.try_get_color(&self.fallback).unwrap_or_default()
}
/// Try to get actual color from [ConfigColor].
/// Returns None if it is [ConfigColor::Alias] and alias was not found in [Colors::aliases]
#[inline(always)]
pub fn try_get_color(&self, color: &ConfigColor) -> Option<Color> {
match color {
ConfigColor::Raw(color) => Some(argb(*color)),
ConfigColor::Alias(alias) => self.aliases.get(alias).map(|c| argb(*c)),
}
}
/// Get either the color or fallback color
#[inline(always)]
pub fn get_color(&self, color: &ConfigColor) -> Color {
self.try_get_color(color).unwrap_or_else(|| self.fallback_color())
}
/// Compute hash and choose a color for the given event string
/// This way same strings will get same colors but it still feels randomly
pub fn event_color_for(&self, text: &str) -> &EventColor {
let priority_sum: u64 = self.events.iter().map(|e| e.priority).sum();

View file

@ -13,15 +13,15 @@ pub(super) struct DefaultConfig {
}
#[derive(Deserialize)]
pub struct DefaultColors {
pub aliases: HashMap<String, u32>,
pub(super) struct DefaultColors {
pub(super) aliases: HashMap<String, u32>,
pub background: ConfigColor,
pub timeline: ConfigColor,
pub text: ConfigColor,
pub fallback: ConfigColor,
pub(super) background: ConfigColor,
pub(super) timeline: ConfigColor,
pub(super) text: ConfigColor,
pub(super) fallback: ConfigColor,
pub events: Vec<EventColor>,
pub(super) events: Vec<EventColor>,
}
impl From<DefaultColors> for Colors {
@ -38,8 +38,8 @@ impl From<DefaultColors> for Colors {
}
#[derive(Deserialize)]
pub struct DefaultPaths {
pub logs: PathBuf,
pub(super) struct DefaultPaths {
pub(super) logs: PathBuf,
}
impl From<DefaultPaths> for Paths {

View file

@ -2,12 +2,16 @@ use std::path::PathBuf;
use serde::{Deserialize, Serialize};
use color::Colors;
/// Color-related structs and methods
pub mod color;
// Not very optimal, but needed to avoid recursion in Config::default
mod default;
/// Paths which are used by Aliveline
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
#[serde(default)]
pub struct Paths {
/// Path to logs folder
pub logs: PathBuf,
}
@ -17,17 +21,21 @@ impl Default for Paths {
}
}
/// Configuration struct
#[derive(Serialize, Deserialize, Default, Clone, PartialEq, Eq, Debug)]
#[serde(default)]
pub struct Config {
/// directory, where config is located
/// Directory, where config is located
#[serde(skip)]
pub conf_path: PathBuf,
/// Config colors
pub colors: Colors,
/// Config paths
pub paths: Paths,
}
impl Config {
/// Get the default config and make it think it is in the given [PathBuf]
pub fn new(conf_path: PathBuf) -> Self {
let conf_dir: PathBuf = conf_path.parent().unwrap().into();
Config {
@ -36,6 +44,7 @@ impl Config {
}
}
// replace fields that are not filled from deserializing
fn replace_missing_fields(&mut self) {
let default = Config::default();
@ -43,7 +52,8 @@ impl Config {
self.colors.events = default.colors.events;
}
}
/// Try to load [Config] from given [PathBuf]
pub fn load(path: PathBuf) -> Option<Self> {
if let Ok(toml_string) = std::fs::read_to_string(path.clone()) {
if let Ok(mut conf) = toml::from_str::<Config>(&toml_string) {

View file

@ -1,7 +1,9 @@
use config::Config;
use std::path::PathBuf;
/// Configuration module
pub mod config;
/// Event tracking module
pub mod log;
fn try_config_path(var: &'static str, path: &[&'static str]) -> Option<Config> {

View file

@ -6,17 +6,22 @@ use serde::{Deserialize, Serialize};
use toml::value::{Date, Time};
use crate::config::Config;
/// Contains all activity tracked in one day
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct Log {
/// Logging date, should match its filename
pub date: Date,
/// Recorded events
pub events: Vec<Event>,
}
impl Log {
/// Construct new empty log for given date
pub fn new(date: Date) -> Self {
Log { date, events: Vec::new() }
}
/// Load log from [Paths::logs](crate::config::Paths::logs) or get empty log
pub fn load_from(config: &Config, date: Date) -> Self {
let path = Log::get_filepath(&date, config);
if let Ok(log_string) = std::fs::read_to_string(path) {
@ -25,7 +30,8 @@ impl Log {
Log::new(date)
}
}
/// Save log in [Paths::logs](crate::config::Paths::logs)
pub fn save(&self, config: &Config) -> std::io::Result<()> {
Log::try_create_log_dir(config)?;
let path = Log::get_filepath(&self.date, config);
@ -36,7 +42,8 @@ impl Log {
}
}
}
// get filepath based on log date
fn get_filepath(date: &Date, config: &Config) -> PathBuf {
let mut path = Log::get_log_dir(&config);
let filename = format!("{}-{}-{}", date.day, date.month, date.year);
@ -44,7 +51,8 @@ impl Log {
path.set_extension("toml");
path
}
// get logging directory based on relativeness in the config
fn get_log_dir(config: &Config) -> PathBuf {
if config.paths.logs.is_relative() {
let mut path = config.conf_path.clone();
@ -54,7 +62,8 @@ impl Log {
return config.paths.logs.clone();
}
}
// create logging directory if it does not exist
fn try_create_log_dir(config: &Config) -> std::io::Result<()> {
let path = Log::get_log_dir(config);
if !std::fs::exists(&path)? {
@ -64,15 +73,21 @@ impl Log {
}
}
/// Single event with duration and a name
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
pub struct Event {
/// Event name string
pub name: String,
/// When the event began
pub start: Time,
/// When the event finished (if it is)
pub end: Time,
/// Is the event finished or it continues
pub finished: bool,
}
impl Event {
/// Construct new event from time seconds
pub fn new(name: String, start: i32, end: i32, finished: bool) -> Self {
let start = Time {
hour: (start / 3600) as u8,