docs: Added some code documentation
This commit is contained in:
parent
ba7bc67b6c
commit
4c2ddde26f
5 changed files with 70 additions and 20 deletions
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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> {
|
||||
|
|
|
|||
23
src/log.rs
23
src/log.rs
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue