1use super::prelude::*;
4use rand::Rng;
5
6const MOTD: &[&str] = &["And don't work too much!", "Work smarter, not harder."];
7
8#[derive(Clone, Debug)]
10pub enum Operation {
11 None,
13 Intro,
15 Push(usize, Job),
17 Modify(usize, Job),
19 Delete(Positions),
21 Import(String, usize, TagSet),
23 Configure(Option<TagSet>, Properties),
25 List(Positions, Range, Option<TagSet>),
27 Report(Positions, Range, Option<TagSet>),
29 ExportCSV(Positions, Range, Option<TagSet>, Columns),
31 ListTags(TagSet),
33 ShowConfiguration(Configuration),
35}
36
37impl Operation {
38 pub fn reports_open_job(&self) -> bool {
39 matches!(self, Operation::Intro | Operation::Push(_, _))
40 }
41}
42
43impl std::fmt::Display for Operation {
44 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
45 match self {
46 Operation::None => Ok(()),
47 Operation::Intro => {
48 let mut rng = rand::thread_rng();
49 let motd = MOTD[rng.gen_range(0..MOTD.len())];
50 write!(f, "\n{}", motd)
51 }
52 Operation::Push(position, job) => {
53 if job.is_open() {
54 write!(f, "Started new job:\n\n Pos: {}\n{job}", position + 1)
55 } else {
56 write!(f, "Added new job:\n\n Pos: {}\n{job}", position + 1)
57 }
58 }
59 Operation::Modify(position, job) => {
60 if job.is_open() {
61 write!(f, "Modified open job:\n\n Pos: {}\n{job}", position + 1)
62 } else {
63 write!(f, "Modified job:\n\n Pos: {}\n{job}", position + 1)
64 }
65 }
66 Operation::Delete(positions) => {
67 write!(
68 f,
69 "Deleting job(s) at position(s): {}",
70 positions.into_ranges()
71 )
72 }
73 Operation::Import(filename, count, new_tags) => {
74 if new_tags.is_empty() {
75 write!(f, "Imported {count} jobs from {filename}.")
76 } else {
77 write!(
78 f,
79 "Imported {count} jobs from {filename} (added new tags {new_tags})."
80 )
81 }
82 }
83 Operation::Configure(tags, config) => {
84 if let Some(tags) = tags {
85 write!(
86 f,
87 "Changed the following configuration values for tag(s) {}:\n\n{}",
88 tags, config
89 )
90 } else {
91 write!(
92 f,
93 "Changed the following default configuration values:\n\n{}",
94 config
95 )
96 }
97 }
98 Operation::List(_, range, tags) => {
99 if let Some(tags) = tags {
100 write!(f, "Listed {range} with tags {tags}.")?;
101 } else {
102 write!(f, "Listed {range}:")?;
103 }
104 Ok(())
105 }
106 Operation::Report(_, range, tags) => {
107 if let Some(tags) = tags {
108 write!(f, "Reported {range} with tags {tags}.")?;
109 } else {
110 write!(f, "Reported {range}:")?;
111 }
112 Ok(())
113 }
114 Operation::ExportCSV(_, range, tags, columns) => {
115 if let Some(tags) = tags {
116 write!(f, "Exported {columns} from {range} with tags {tags}.")?;
117 } else {
118 write!(f, "Exported {columns} from {range}:")?;
119 }
120 Ok(())
121 }
122 Operation::ListTags(tags) => {
123 if tags.is_empty() {
124 write!(f, "Currently no tags are used.")
125 } else {
126 write!(f, "Known tags: {}", tags)
127 }
128 }
129 Operation::ShowConfiguration(configuration) => {
130 writeln!(f, "Base Configuration:\n\n{}", configuration.base)?;
132 for (tag, properties) in &configuration.tags {
134 write!(
135 f,
136 "Configuration for tag {}:\n\n{}",
137 TagSet::from(tag.as_str()),
138 properties
139 )?;
140 }
141 Ok(())
142 }
143 }
144 }
145}