aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--karlc/src/main.rs75
-rw-r--r--karlc/src/pretty.rs35
-rw-r--r--karld/src/condition.rs36
3 files changed, 109 insertions, 37 deletions
diff --git a/karlc/src/main.rs b/karlc/src/main.rs
index ef56fd9..e95b5b7 100644
--- a/karlc/src/main.rs
+++ b/karlc/src/main.rs
@@ -1,4 +1,5 @@
pub mod client;
+pub mod pretty;
use chrono::{NaiveDateTime, Utc};
use clap::{Args, Parser, Subcommand};
@@ -7,6 +8,8 @@ use karlcommon::{socket_path, version, ClientboundPacket, ServerboundPacket, Tas
use log::{error, info};
use std::{os::unix::net::UnixStream, path::PathBuf, process::exit};
+use crate::pretty::fmt_condition;
+
/// CLI interface for karld
#[derive(Parser)]
#[clap(about, author, version)]
@@ -81,43 +84,45 @@ fn main() {
client.send(ServerboundPacket::ListTasks);
if let ClientboundPacket::TaskList(tasks) = client.receiver.recv().unwrap() {
for t in tasks {
- print!(
- "
-- \x1b[4m\x1b[1mTASK {}\x1b[0m
- \x1b[38;2;100;255;100mName:\x1b[0m {}
- \x1b[38;2;100;255;100mDescription:\x1b[0m {}
- \x1b[38;2;100;255;100mOccurence:\x1b[0m {:?}
- \x1b[38;2;100;255;100mNext instances: \x1b[0m",
- t.id,
- t.name,
+ println!("- \x1b[4m\x1b[1mTASK {}\x1b[0m", t.id);
+ println!(" \x1b[38;2;100;255;100mName:\x1b[0m {}", t.name);
+ println!(
+ " \x1b[38;2;100;255;100mDescription:\x1b[0m {}",
t.description
- .unwrap_or("\x1b[3m\x1b[2m(no description)\x1b[0m".to_string()),
- t.occurence
+ .unwrap_or("\x1b[3m\x1b[2m(no description)\x1b[0m".to_string())
);
- client.send(ServerboundPacket::ListInstances {
- task: t.id,
- limit: 5,
- range: Some(Utc::now().naive_local().timestamp())..None,
- });
- if let ClientboundPacket::InstanceList(instances) =
- client.receiver.recv().unwrap()
- {
- for i in instances {
- println!(
- "\x1b[19G{} - {}",
- i.at.start
- .map(|e| format!(
- "{}",
- NaiveDateTime::from_timestamp(e as i64, 0)
- ))
- .unwrap_or("...".to_string()),
- i.at.end
- .map(|e| format!(
- "{}",
- NaiveDateTime::from_timestamp(e as i64, 0)
- ))
- .unwrap_or("...".to_string()),
- );
+ if let Some(o) = t.occurence {
+ println!(
+ " \x1b[38;2;100;255;100mOccurence:\x1b[0m {}",
+ fmt_condition(&o)
+ );
+ print!(" \x1b[38;2;100;255;100mNext instances: \x1b[0m");
+
+ client.send(ServerboundPacket::ListInstances {
+ task: t.id,
+ limit: 5,
+ range: Some(Utc::now().naive_local().timestamp())..None,
+ });
+ if let ClientboundPacket::InstanceList(instances) =
+ client.receiver.recv().unwrap()
+ {
+ for i in instances {
+ println!(
+ "\x1b[19G{} - {}",
+ i.at.start
+ .map(|e| format!(
+ "{}",
+ NaiveDateTime::from_timestamp(e as i64, 0)
+ ))
+ .unwrap_or("...".to_string()),
+ i.at.end
+ .map(|e| format!(
+ "{}",
+ NaiveDateTime::from_timestamp(e as i64, 0)
+ ))
+ .unwrap_or("...".to_string()),
+ );
+ }
}
}
println!();
diff --git a/karlc/src/pretty.rs b/karlc/src/pretty.rs
new file mode 100644
index 0000000..bf9cf20
--- /dev/null
+++ b/karlc/src/pretty.rs
@@ -0,0 +1,35 @@
+use karlcommon::Condition;
+
+pub fn indent(s: &str) -> String {
+ s.replace("\n", "\n ")
+}
+
+pub fn fmt_condition(c: &Condition) -> String {
+ match c {
+ Condition::From(_) => todo!(),
+ Condition::Or(_) => todo!(),
+ Condition::And(cs) => cs
+ .iter()
+ .map(|e| fmt_condition(e))
+ .reduce(|a, b| format!("{} ∧ {}", a, b))
+ .unwrap_or("never".to_string()),
+ Condition::Invert(_) => todo!(),
+ Condition::Equal {
+ prop,
+ value,
+ modulus,
+ } => {
+ if let Some(m) = modulus {
+ format!("{:?} ≡ {} (mod {})", prop, value, m)
+ } else {
+ format!("{:?} = {}", prop, value)
+ }
+ }
+ Condition::Range {
+ prop: _,
+ min: _,
+ max: _,
+ modulus: _,
+ } => todo!(),
+ }
+}
diff --git a/karld/src/condition.rs b/karld/src/condition.rs
index a989a25..db1cf1d 100644
--- a/karld/src/condition.rs
+++ b/karld/src/condition.rs
@@ -26,6 +26,29 @@ pub enum Direction {
pub trait ConditionFind {
fn find(&self, edge: Edge, dir: Direction, from: NaiveDateTime) -> Option<NaiveDateTime>;
+
+ fn find_inverse_inclusive(
+ &self,
+ edge: Edge,
+ dir: Direction,
+ from: NaiveDateTime,
+ ) -> Option<NaiveDateTime> {
+ let s = self.find(edge, dir, from);
+ let e = self.find(edge.invert(), dir, from);
+ // we are "inside"
+ match (s, e) {
+ (Some(s), Some(e)) => {
+ if s > e {
+ self.find(edge, dir.invert(), from)
+ } else {
+ Some(s)
+ }
+ }
+ (None, Some(_)) => self.find(edge, dir.invert(), from),
+ (Some(s), None) => Some(s),
+ (None, None) => None,
+ }
+ }
}
impl ConditionFind for Condition {
@@ -35,7 +58,7 @@ impl ConditionFind for Condition {
// TODO improve efficiency for backward search
let last_start = cs
.iter()
- .map(|c| c.find(Start, dir, from))
+ .map(|c| c.find_inverse_inclusive(Start, dir, from))
.reduce(|a, b| Some(max(a?, b?)))?;
let first_end = cs
.iter()
@@ -50,7 +73,7 @@ impl ConditionFind for Condition {
End => end,
});
} else {
- from = start - Duration::seconds(10); // TODO proper fix
+ from = start - Duration::seconds(1); // TODO proper fix
}
}
None => break Some(start),
@@ -242,6 +265,15 @@ impl Edge {
}
}
+impl Direction {
+ pub fn invert(self) -> Self {
+ match self {
+ Direction::Forward => Direction::Backward,
+ Direction::Backward => Direction::Forward,
+ }
+ }
+}
+
#[cfg(test)]
mod test {
use super::{Condition, ConditionFind, Direction, Edge, Property};