diff options
author | metamuffin <yvchraiqi@protonmail.com> | 2022-06-10 17:48:32 +0200 |
---|---|---|
committer | metamuffin <yvchraiqi@protonmail.com> | 2022-06-10 17:48:32 +0200 |
commit | 45f2d1651f17d7e155748cfd1e1cd9a96f3e530e (patch) | |
tree | 6847a4552db06b56a5e0a55aa56354eccb7c41b1 | |
parent | d65b915f3dfda28aad6f2806df38c8ad77135d8b (diff) | |
download | karlender-45f2d1651f17d7e155748cfd1e1cd9a96f3e530e.tar karlender-45f2d1651f17d7e155748cfd1e1cd9a96f3e530e.tar.bz2 karlender-45f2d1651f17d7e155748cfd1e1cd9a96f3e530e.tar.zst |
better cli
-rw-r--r-- | Cargo.lock | 48 | ||||
-rw-r--r-- | karlc/Cargo.toml | 2 | ||||
-rw-r--r-- | karlc/src/client.rs | 20 | ||||
-rw-r--r-- | karlc/src/main.rs | 77 | ||||
-rw-r--r-- | karlcommon/src/protocol.rs | 13 | ||||
-rw-r--r-- | karld/src/interface.rs | 7 | ||||
-rw-r--r-- | karld/src/main.rs | 18 |
7 files changed, 159 insertions, 26 deletions
@@ -133,6 +133,17 @@ dependencies = [ ] [[package]] +name = "getrandom" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] name = "hashbrown" version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -185,6 +196,7 @@ dependencies = [ "env_logger", "karlcommon", "log", + "rand", "serde", "serde_json", ] @@ -264,6 +276,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21326818e99cfe6ce1e524c2a805c189a99b5ae555a35d19f9a284b427d86afa" [[package]] +name = "ppv-lite86" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" + +[[package]] name = "proc-macro-error" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -306,6 +324,36 @@ dependencies = [ ] [[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom", +] + +[[package]] name = "regex" version = "1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/karlc/Cargo.toml b/karlc/Cargo.toml index f95dee0..653933a 100644 --- a/karlc/Cargo.toml +++ b/karlc/Cargo.toml @@ -13,3 +13,5 @@ env_logger = "0.9.0" log = "0.4.17" crossbeam-channel = "0.5.4" chrono = { version = "0.4.19", features = ["serde"] } +rand = "0.8.5" + diff --git a/karlc/src/client.rs b/karlc/src/client.rs index 6420da0..e7ca44d 100644 --- a/karlc/src/client.rs +++ b/karlc/src/client.rs @@ -5,8 +5,8 @@ use std::{ }; use crossbeam_channel::Receiver; -use karlcommon::{ClientboundPacket, ServerboundPacket}; -use log::debug; +use karlcommon::{version, ClientboundPacket, ServerboundPacket}; +use log::{debug, error}; pub struct Client { socket: UnixStream, @@ -17,18 +17,20 @@ impl Client { pub fn new(socket: UnixStream) -> Self { let (sender, receiver) = crossbeam_channel::unbounded(); let mut reader = BufReader::new(socket.try_clone().unwrap()); - thread::spawn(move || { - loop { - let mut buf = String::new(); - reader.read_line(&mut buf).unwrap(); - let p: ClientboundPacket = serde_json::from_str(buf.as_str()).unwrap(); - debug!("<- {:?}", p); + thread::spawn(move || loop { + let mut buf = String::new(); + reader.read_line(&mut buf).unwrap(); + let p: ClientboundPacket = serde_json::from_str(buf.as_str()).unwrap(); + debug!("<- {:?}", p); + if let ClientboundPacket::Error(e) = p { + error!("daemon reported error: {:?}", e); + } else { sender.send(p).unwrap(); } }); let mut c = Self { receiver, socket }; c.send(ServerboundPacket::Handshake { - version: env!("CARGO_PKG_VERSION").to_owned(), + version: version!(), }); return c; } diff --git a/karlc/src/main.rs b/karlc/src/main.rs index 9a89de9..ef56fd9 100644 --- a/karlc/src/main.rs +++ b/karlc/src/main.rs @@ -1,16 +1,19 @@ pub mod client; use chrono::{NaiveDateTime, Utc}; -use clap::{Parser, Subcommand}; +use clap::{Args, Parser, Subcommand}; use client::Client; -use karlcommon::{socket_path, version, ClientboundPacket, ServerboundPacket}; +use karlcommon::{socket_path, version, ClientboundPacket, ServerboundPacket, Task}; use log::{error, info}; -use std::{os::unix::net::UnixStream, process::exit}; +use std::{os::unix::net::UnixStream, path::PathBuf, process::exit}; /// CLI interface for karld #[derive(Parser)] #[clap(about, author, version)] -struct Args { +struct Arguments { + /// Custom path to the daemon socket + #[clap(long)] + socket_path: Option<PathBuf>, #[clap(subcommand)] action: Action, } @@ -21,13 +24,36 @@ pub enum Action { Version, /// List all tasks List, + /// Remove a task by id + Remove { id: u64 }, + /// Update a task by id + Update { + id: u64, + #[clap(flatten)] + task: TaskSpec, + }, + /// Create a task + Create { + #[clap(flatten)] + task: TaskSpec, + }, +} + +#[derive(Args)] +pub struct TaskSpec { + #[clap(short, long)] + name: String, + #[clap(short, long)] + description: Option<String>, + #[clap(short, long)] + tags: Vec<String>, } fn main() { env_logger::init(); - let args = Args::parse(); + let args = Arguments::parse(); - let socket = match UnixStream::connect(socket_path()) { + let socket = match UnixStream::connect(args.socket_path.unwrap_or(socket_path())) { Ok(s) => s, Err(e) => { error!("failed to connect to socket: {}", e); @@ -62,7 +88,11 @@ fn main() { \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, t.description, t.occurence + t.id, + t.name, + t.description + .unwrap_or("\x1b[3m\x1b[2m(no description)\x1b[0m".to_string()), + t.occurence ); client.send(ServerboundPacket::ListInstances { task: t.id, @@ -94,5 +124,38 @@ fn main() { } } } + Action::Remove { id } => { + client.send(ServerboundPacket::RemoveTask(id)); + } + Action::Update { id, task } => { + let mut t = task.build(); + t.id = id; + client.send(ServerboundPacket::UpdateTask(t)) + } + Action::Create { task } => client.send(ServerboundPacket::UpdateTask(task.build())), + } + + // sync + client.send(ServerboundPacket::Sync); + for p in client.receiver.iter() { + if let ClientboundPacket::Sync = p { + break; + } + } +} + +impl TaskSpec { + pub fn build(self) -> Task { + Task { + id: rand::random(), + name: self.name, + description: self.description, + tags: self.tags, + priority: 0.0, + completed: None, + scheduled: None, + occurence: None, + deadline: None, + } } } diff --git a/karlcommon/src/protocol.rs b/karlcommon/src/protocol.rs index e5bb9f0..a86ca3d 100644 --- a/karlcommon/src/protocol.rs +++ b/karlcommon/src/protocol.rs @@ -6,14 +6,23 @@ use serde::{Deserialize, Serialize}; #[serde(tag = "type", content = "data", rename_all = "snake_case")] pub enum ClientboundPacket { Handshake { version: String }, - Error(String), + Error(ProtoError), TaskList(Vec<Task>), InstanceList(Vec<Instance>), + Sync, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(tag = "type", content = "data", rename_all = "snake_case")] +pub enum ProtoError { + UnknownTask, + FormatError(String), } #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(tag = "type", content = "data", rename_all = "snake_case")] pub enum ServerboundPacket { + Sync, Handshake { version: String, }, @@ -31,7 +40,7 @@ pub enum ServerboundPacket { pub struct Task { pub id: u64, pub name: String, - pub description: String, + pub description: Option<String>, pub tags: Vec<String>, pub priority: f64, diff --git a/karld/src/interface.rs b/karld/src/interface.rs index 127c0db..750f307 100644 --- a/karld/src/interface.rs +++ b/karld/src/interface.rs @@ -1,5 +1,5 @@ use crate::handle_packet; -use karlcommon::{socket_path, version, ClientboundPacket, ServerboundPacket}; +use karlcommon::{socket_path, version, ClientboundPacket, ProtoError, ServerboundPacket}; use log::{debug, error, info, warn}; use std::io; use std::io::{BufRead, BufReader, ErrorKind, Write}; @@ -61,7 +61,10 @@ fn handle_connection(id: u32, mut stream: UnixStream) -> io::Result<()> { Err(err) => { warn!("client error: {:?}", &err); responder - .send(ClientboundPacket::Error(format!("{}", &err))) + .send(ClientboundPacket::Error(ProtoError::FormatError(format!( + "{}", + &err + )))) .map_err(|_| io::Error::from(ErrorKind::InvalidInput))? } } diff --git a/karld/src/main.rs b/karld/src/main.rs index 1bc5798..0983554 100644 --- a/karld/src/main.rs +++ b/karld/src/main.rs @@ -5,7 +5,9 @@ use chrono::NaiveDateTime; use condition::ConditionFind; use crossbeam_channel::Sender; use interface::network_loop; -use karlcommon::{ClientboundPacket, Condition, Instance, Property, ServerboundPacket, Task}; +use karlcommon::{ + ClientboundPacket, Condition, Instance, Property, ProtoError, ServerboundPacket, Task, +}; use log::{debug, info}; use std::{collections::HashMap, sync::RwLock}; @@ -16,8 +18,8 @@ fn main() { 0, Task { id: 0, - name: "blub".to_string(), - description: "blob".to_string(), + name: "Mittagessen im Februar".to_string(), + description: None, tags: vec![], priority: 69.0, completed: None, @@ -46,6 +48,9 @@ lazy_static::lazy_static! { pub fn handle_packet(client: u32, packet: ServerboundPacket, responder: Sender<ClientboundPacket>) { match packet { + ServerboundPacket::Sync => { + let _ = responder.send(ClientboundPacket::Sync); + } ServerboundPacket::ListTasks => { let _ = responder.send(ClientboundPacket::TaskList( TASKS.read().unwrap().values().map(|e| e.clone()).collect(), @@ -55,7 +60,9 @@ pub fn handle_packet(client: u32, packet: ServerboundPacket, responder: Sender<C TASKS.write().unwrap().insert(t.id, t); } ServerboundPacket::RemoveTask(i) => { - TASKS.write().unwrap().remove(&i); + if TASKS.write().unwrap().remove(&i).is_none() { + let _ = responder.send(ClientboundPacket::Error(ProtoError::UnknownTask)); + } } ServerboundPacket::Handshake { version } => { debug!("{client}: version {version}"); @@ -64,8 +71,7 @@ pub fn handle_packet(client: u32, packet: ServerboundPacket, responder: Sender<C let t = match TASKS.read().unwrap().get(&task).cloned() { Some(t) => t, None => { - let _ = - responder.send(ClientboundPacket::Error("task does not exist".to_string())); + let _ = responder.send(ClientboundPacket::Error(ProtoError::UnknownTask)); return; } }; |