use std::num::NonZero; use chrono::{DateTime, Utc}; use orchid_api_derive::{Coding, Hierarchy}; use orchid_api_traits::Request; use crate::api; use crate::atom::AtomMethod; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Coding, Hierarchy)] pub struct Spawn(pub api::ExprTicket); impl Request for Spawn { type Response = api::ExprTicket; } /// Execute the atom as a command. #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Coding, Hierarchy)] pub struct RunCommand; impl Request for RunCommand { type Response = Option; } impl AtomMethod for RunCommand { const NAME: &str = "orchid::cmd::run"; } #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Coding, Hierarchy)] pub struct AsInstant; impl Request for AsInstant { type Response = DateTime; } impl AtomMethod for AsInstant { const NAME: &str = "orchid::time::as_duration"; } /// Represents [std::io::ErrorKind] values that are produced while operating on /// already-opened files #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Coding)] pub enum IoErrorKind { /// Produced when a stream ends prematurely due to an identifiably unintended /// reason, such as a TCP socket timeout, the file becoming inaccessible or /// disappearing, or Interrupted, Other, } impl IoErrorKind { pub fn message(self) -> &'static str { match self { IoErrorKind::Other => "Failed to read from stream", IoErrorKind::Interrupted => "Stream interrupted", } } } /// Represents [std::io::Error] values that are produced while operating on /// already-opened files #[derive(Clone, Debug, Coding)] pub struct IoError { pub message: String, pub kind: IoErrorKind, } #[derive(Clone, Debug, Coding)] pub enum ReadLimit { End, Delimiter(u8), Length(NonZero), } /// Read all available data from a stream. If the returned vector is empty, the /// stream has reached its end. #[derive(Clone, Debug, Coding, Hierarchy)] pub struct ReadReq(pub ReadLimit); impl Request for ReadReq { type Response = Result, IoError>; } impl AtomMethod for ReadReq { const NAME: &str = "orchid::stream::read"; } /// Write the specified number of bytes into a stream. #[derive(Clone, Debug, Coding, Hierarchy)] #[extends(OutputReq)] pub struct WriteReq { pub data: Vec, } impl Request for WriteReq { type Response = Result<(), IoError>; } /// Flush a stream, ensuring that all data reached its destination. #[derive(Clone, Debug, Coding, Hierarchy)] #[extends(OutputReq)] pub struct FlushReq; impl Request for FlushReq { type Response = Result<(), IoError>; } /// Close a stream, indicating that no further data will be sent through it. #[derive(Clone, Debug, Coding, Hierarchy)] #[extends(OutputReq)] pub struct CloseReq; impl Request for CloseReq { type Response = Result<(), IoError>; } /// Operations on outbound streams across extension boundaries. #[derive(Clone, Debug, Coding, Hierarchy)] #[extendable] #[allow(clippy::enum_variant_names)] pub enum OutputReq { WriteReq(WriteReq), FlushReq(FlushReq), CloseReq(CloseReq), } impl AtomMethod for OutputReq { const NAME: &str = "orchid::stream::write"; }