#![allow(clippy::manual_range_contains)] #![warn(rust_2018_idioms)] #![forbid(elided_lifetimes_in_paths, unsafe_code)] mod iotro; mod render; mod time; use crate::{ render::Renderer, time::{parse_date, parse_time, Date, Time} }; use camino::Utf8PathBuf as PathBuf; use clap::Parser; use rational::Rational; use serde::{Deserialize, Serialize}; use serde_with::{serde_as, DisplayFromStr}; use std::{ collections::BTreeSet, fmt::Display, fs, io::{self, BufRead as _, Write}, sync::RwLock }; static MEM_LIMIT: RwLock = RwLock::new(String::new()); #[derive(Debug, Parser)] struct Args { #[clap(short = 'C', long, default_value = ".")] directory: PathBuf, #[clap(short = 'c', long, default_value = "23ws-malo")] course: String, #[clap(short, long, default_value = "2G")] mem_limit: String } #[allow(non_camel_case_types, clippy::upper_case_acronyms)] #[derive(Clone, Copy, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)] enum Resolution { /// 640x360 nHD, /// 1280x720 HD, /// 1920x1080 FullHD, /// 2560x1440 WQHD, /// 3840x2160 UHD } impl Resolution { fn width(self) -> usize { match self { Self::nHD => 640, Self::HD => 1280, Self::FullHD => 1920, Self::WQHD => 2560, Self::UHD => 3840 } } fn height(self) -> usize { match self { Self::nHD => 360, Self::HD => 720, Self::FullHD => 1080, Self::WQHD => 1440, Self::UHD => 2160 } } } #[derive(Deserialize, Serialize)] struct Project { lecture: ProjectLecture, source: ProjectSource, progress: ProjectProgress } #[serde_as] #[derive(Deserialize, Serialize)] struct ProjectLecture { course: String, #[serde_as(as = "DisplayFromStr")] date: Date } #[serde_as] #[derive(Deserialize, Serialize)] struct ProjectSource { files: Vec, #[serde_as(as = "Option")] start: Option