use std::ops::Range; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(tag = "type", content = "data", rename_all = "snake_case")] pub enum ClientboundPacket { Handshake { version: String }, Error(ProtoError), TaskList(Vec), InstanceList(Vec>>), InvalidateState, Sync, } #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(tag = "kind", content = "details", 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, }, ListTasks, ListInstances { task: u64, range: Range>, limit: usize, }, UpdateTask(Task), RemoveTask(u64), } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Task { pub id: u64, pub name: String, pub description: Option, pub tags: Vec, pub schedule: Schedule, } #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(tag = "type", content = "options", rename_all = "snake_case")] pub enum Schedule { Never, Dynamic { priority: f64, scheduled: Option>, duration: i64, condition: Condition, // duration, during which the task should be scheduled }, Condition(Condition), Static(Range), } impl Schedule { /// Returns `true` if the schedule is [`Dynamic`]. /// /// [`Dynamic`]: Schedule::Dynamic pub fn is_dynamic(&self) -> bool { matches!(self, Self::Dynamic { .. }) } } #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] pub enum Condition { Never, From(Box), Or(Vec), And(Vec), Invert(Box), Equal { prop: Property, value: i64, modulus: Option, }, Range { prop: Property, min: i64, max: i64, modulus: Option, }, } #[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "snake_case")] pub enum Property { Year, Monthofyear, Weekofmonth, Dayofyear, Dayofmonth, Dayofweek, Hour, Minute, Second, Unix, }