1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
use std::{
fs,
io,
path::PathBuf,
};
use tinytemplate::TinyTemplate;
use regex::Regex;
use serde::Serialize;
use crate::{Course, Config, rofi_picker};
#[derive(Serialize)]
struct HomeworkContext<'a> {
course: &'a String,
number: u32,
}
fn display_name(name: &String) -> String {
let pattern = Regex::new(r"([a-z]+)(\d{3})").unwrap();
let caps = pattern.captures(name).unwrap();
let dept = caps.get(1).unwrap().as_str().to_uppercase();
let number = caps.get(2).unwrap().as_str();
let display_name = format!("{dept} {number}");
println!("{display_name}");
return display_name;
}
fn init_homework(course: &Course, config: &Config, context: &HomeworkContext) -> (PathBuf, String) {
let template_stream = fs::read(&config.homework_template)
.expect("Couldn't open template.");
let template_string = String::from_utf8_lossy(&template_stream);
let mut template = TinyTemplate::new();
template.add_template("main", &template_string)
.expect("Failed initializing template.");
let rendered = template.render("main", &context)
.expect("Failed applying template");
let homework_file = format!("homework{}.tex", context.number);
let homework_directory = config.root.join(&course.semester).join(&course.name)
.join(format!("homework{}", context.number));
fs::create_dir(&homework_directory).unwrap();
fs::write(homework_directory.join(homework_file.clone()), rendered)
.expect("Failed making main tex for course.");
return (homework_directory, homework_file);
}
fn detect_homeworks(path: &PathBuf) -> io::Result<Vec<u32>> {
let mut homework_numbers: Vec<u32> = Vec::new();
let dir_iter = fs::read_dir(path)?;
let pattern = Regex::new(r"homework(\d+)").unwrap();
for entry in dir_iter {
let entry_path = entry?.path();
let name = entry_path.file_name().unwrap().to_string_lossy();
if let Some(caps) = pattern.captures(&name) {
let homework_number = caps[1].parse::<u32>().unwrap();
homework_numbers.push(homework_number);
}
}
homework_numbers.sort();
return Ok(homework_numbers);
}
pub fn new_homework(course: &Course, config: &Config) -> (PathBuf, String) {
let course_directory = config.root.join(&course.semester).join(&course.name);
if !course_directory.try_exists().unwrap() {
fs::create_dir_all(&course_directory).unwrap();
}
let homeworks = detect_homeworks(&course_directory)
.expect("Could not make sense of the homeworks situation.");
let new_homework = homeworks.last().unwrap_or(&0).clone() + 1;
let name = display_name(&course.name);
let homework_context = HomeworkContext { course: &name, number: new_homework };
return init_homework(course, config, &homework_context);
}
pub fn recent_homework(course: &Course, config: &Config) -> (PathBuf, String) {
let course_directory = config.root.join(&course.semester).join(&course.name);
let homeworks = detect_homeworks(&course_directory)
.expect("Could not make sense of the homeworks situation.");
let most_recent = homeworks.last().expect("No homeworks.");
let homework_directory = course_directory.join(format!("homework{most_recent}"));
let homework_file = format!("homework{most_recent}.tex");
return (homework_directory, homework_file);
}
pub fn view_homeworks(course: &Course, config: &Config) -> Result<(PathBuf, String), &'static str> {
let course_directory = config.root.join(&course.semester).join(&course.name);
let homeworks = detect_homeworks(&course_directory)
.expect("Could not make sense of the homeworks situation.");
let mut homeworks_string = String::new();
for (idx, hw) in homeworks.iter().enumerate() {
if idx != 0 {
homeworks_string.push_str("\n");
}
homeworks_string.push_str(&format!("Homework {hw}").to_string());
}
let hw_idx = rofi_picker("Homeworks", homeworks_string)?;
let picked_homework = homeworks[hw_idx as usize];
let homework_directory = course_directory.join(format!("homework{picked_homework}"));
let homework_file = format!("homework{picked_homework}.tex");
return Ok((homework_directory, homework_file));
}
|