use orchid_api_derive::{Coding, Hierarchy}; use orchid_api_traits::Request; use crate::expr::{Expr, ExprTicket}; use crate::proto::{ExtHostReq, HostExtNotif, HostExtReq}; use crate::system::SysId; pub type AtomData = Vec; /// An atom owned by an implied system. Usually used in responses from a system. /// This has the same semantics as [Atom] except in that the owner is implied. #[derive(Clone, Debug, Hash, PartialEq, Eq, Coding)] pub struct LocalAtom { pub drop: bool, pub data: AtomData, } /// An atom representation that can be serialized and sent around. Atoms /// represent the smallest increment of work. #[derive(Clone, Debug, Hash, PartialEq, Eq, Coding)] pub struct Atom { /// Instance ID of the system that created the atom pub owner: SysId, /// Indicates whether the owner should be notified when this atom is dropped. /// Construction is always explicit and atoms are never cloned. /// /// Atoms with `drop == false` are also known as trivial, they can be /// duplicated and stored with no regard to expression lifetimes. NOTICE /// that this only applies to the atom. If it's referenced with an /// [ExprTicket], the ticket itself can still expire. /// /// Notice also that the atoms still expire when the system is dropped, and /// are not portable across instances of the same system, so this doesn't /// imply that the atom is serializable. pub drop: bool, /// Data stored in the atom. This could be a key into a map, or the raw data /// of the atom if it isn't too big. pub data: AtomData, } /// Attempt to apply an atom as a function to an expression #[derive(Clone, Debug, Hash, PartialEq, Eq, Coding, Hierarchy)] #[extends(AtomReq, HostExtReq)] pub struct CallRef(pub Atom, pub ExprTicket); impl Request for CallRef { type Response = Expr; } /// Attempt to apply an atom as a function, consuming the atom and enabling the /// library to reuse its datastructures rather than duplicating them. This is an /// optimization over [CallRef] followed by [AtomDrop]. #[derive(Clone, Debug, Hash, PartialEq, Eq, Coding, Hierarchy)] #[extends(AtomReq, HostExtReq)] pub struct FinalCall(pub Atom, pub ExprTicket); impl Request for FinalCall { type Response = Expr; } /// Determine whether two atoms are identical for the purposes of macro /// application. If a given atom is never generated by macros or this relation /// is difficult to define, the module can return false #[derive(Clone, Debug, Hash, PartialEq, Eq, Coding, Hierarchy)] #[extends(AtomReq, HostExtReq)] pub struct AtomSame(pub Atom, pub Atom); impl Request for AtomSame { type Response = bool; } /// A request blindly routed to the system that provides an atom. #[derive(Clone, Debug, Hash, PartialEq, Eq, Coding, Hierarchy)] #[extends(AtomReq, HostExtReq)] pub struct Fwded(pub Atom, pub Vec); impl Request for Fwded { type Response = Vec; } #[derive(Clone, Debug, Hash, PartialEq, Eq, Coding, Hierarchy)] #[extends(ExtHostReq)] pub struct Fwd(pub Atom, pub Vec); impl Request for Fwd { type Response = Vec; } /// Notification that an atom is being dropped because its associated expression /// isn't referenced anywhere. This should have no effect if the atom's `drop` /// flag is false. #[derive(Clone, Debug, Hash, PartialEq, Eq, Coding, Hierarchy)] #[extends(HostExtNotif)] pub struct AtomDrop(pub Atom); #[derive(Clone, Debug, Hash, PartialEq, Eq, Coding, Hierarchy)] #[extends(HostExtReq)] #[extendable] pub enum AtomReq { CallRef(CallRef), FinalCall(FinalCall), AtomSame(AtomSame), Fwded(Fwded), }