Skip to main content

behavior/
lib.rs

1//! Pure, typed actor-behavior primitives.
2//!
3//! [`Protocol`] is stable public destination identity (`Addr` plus `Msg`). A
4//! [`Behavior`] separately owns state and folds its complete [`Behavior::Event`]
5//! algebra into exactly [`Actions`]: sends, fresh creations, and its next
6//! behavior or termination. A protocol is not a behavior, and `Behavior` is not
7//! a `Protocol` supertrait. Higher capabilities extend internal event and
8//! effect algebras while transparent wrappers preserve [`Behavior::Protocol`].
9
10// The `#[behavior]` expansion emits `::behavior::…` paths; this alias lets the
11// expansion resolve inside this crate too.
12extern crate self as behavior;
13
14mod actor;
15mod effect;
16mod effects;
17mod next;
18mod reducer;
19mod transition;
20mod user_event;
21
22pub use actor::{
23    Address, BirthMode, BirthNodeProtocols, BirthProtocol, BirthProtocolAt, BirthProtocolHead,
24    BirthProtocolProduct, BirthProtocolTail, BirthProtocols, Births, ChildChoice, ChildCons,
25    ChildHead, ChildPosition, ChildProduct, ChildRecipient, ChildRole, ChildRoute, ChildTail,
26    Children, ChildrenError, Create, CreationKind, Delivery, DeliveryTarget, DispatchBirth,
27    InstallBirth, MailAddr, NoBirthProtocols, NoBirths, NoChildren, Recipient,
28};
29pub use effect::Effect;
30pub use effects::{
31    Acted, Actions, AppendSend, Become, InterpretDelivery, InterpretRequest, InterpretSends,
32    InterpreterRequest, InterpreterRequests, NoReturnToEmitter, NoSends, Own, ReturnsToEmitter,
33    SendEffects, SendInput, SendInterpreter, SendLayer, SendsFor,
34};
35pub use next::{Never, Step, Stopped};
36pub use reducer::{ActionReducer, Effects, FoldFailure, Folded, fold_events};
37pub use transition::{
38    ActiveTurn, Behavior, BehaviorActed, BehaviorAddr, BehaviorBase, BehaviorMessage,
39    InitializationTurn, MessageProtocol, Protocol, delegate_transition, initialize,
40};
41pub use user_event::{
42    ComposedEvent, EventLayer, Here, Ingress, InjectEvent, Inside, User, UserEvent,
43};
44
45/// Generate the nominal protocol, closed effect products, and exact `Behavior`
46/// wiring for an inherent impl. `addr` and `message` are required. Omitting
47/// `sends`, `births`, or `error` selects the capability-free `NoSends`,
48/// `NoBirths`, or `Never` type respectively.
49///
50/// A `sends = { lane: Product }` declaration generates `ActorSends`, one
51/// distinct `ActorSendsLane` selector per field, and structural `SendEffects`,
52/// `SendsFor`, and `InterpretSends` implementations. It also generates an
53/// `ActorActions` extension trait with one fluent `send_lane` method per named
54/// lane. Each method delegates to [`AppendSend`], changing only the send leg
55/// while preserving creations and the exact next-behavior verdict. A
56/// `births = { lane: Child }` declaration generates `ActorChildren` as the
57/// exact recursive `ChildChoice` produced by `Children` calls in declaration
58/// order. It also generates `ActorChildrenRoutes`, containing one nominally
59/// distinct [`ChildRoute`] per declared role. A route is the single typed
60/// source for staging that role's creation and addressing its creator-local
61/// recipient. Creation remains an authored [`Children`] value and is never
62/// performed by the macro.
63///
64/// Invalid receivers are rejected at compile time.
65///
66/// ```compile_fail
67/// use behavior::{Actions, BehaviorActed, MailAddr};
68///
69/// struct Invalid;
70/// #[behavior::behavior(
71///     addr = MailAddr,
72///     message = u8,
73/// )]
74/// impl Invalid {
75///     fn init(&self) -> BehaviorActed<Self> {
76///         Ok(Actions::cont())
77///     }
78///     fn receive(&mut self, _: MailAddr, _: u8) -> BehaviorActed<Self> {
79///         Ok(Actions::cont())
80///     }
81/// }
82/// ```
83///
84/// Missing receive methods are rejected by the macro itself:
85///
86/// ```compile_fail
87/// use behavior::MailAddr;
88/// struct Missing;
89/// #[behavior::behavior(
90///     addr = MailAddr,
91///     message = u8,
92/// )]
93/// impl Missing {
94/// }
95/// ```
96///
97/// Async behavior methods cannot introduce an erased or alternate execution
98/// path:
99///
100/// ```compile_fail
101/// use behavior::{Actions, BehaviorActed, MailAddr};
102/// struct Async;
103/// #[behavior::behavior(
104///     addr = MailAddr,
105///     message = u8,
106/// )]
107/// impl Async {
108///     async fn init(&mut self) -> BehaviorActed<Self> {
109///         Ok(Actions::cont())
110///     }
111///     fn receive(&mut self, _: MailAddr, _: u8) -> BehaviorActed<Self> {
112///         Ok(Actions::cont())
113///     }
114/// }
115/// ```
116///
117/// Undeclared send lanes have no selector and cannot be emitted:
118///
119/// ```compile_fail
120/// use behavior::{Actions, BehaviorActed, MailAddr, SendEffects};
121/// struct Sender;
122/// #[behavior::behavior(addr = MailAddr, message = (), sends = { replies: Vec<u8> })]
123/// impl Sender {
124///     fn receive(&mut self, _: MailAddr, _: ()) -> BehaviorActed<Self> {
125///         let mut sends = SenderSends::empty();
126///         sends.send::<_, SenderSendsUndeclared>(1);
127///         Ok(Actions::send(sends))
128///     }
129/// }
130/// ```
131///
132/// Generated lane methods accept only inputs supported by that lane:
133///
134/// ```compile_fail
135/// use behavior::{Actions, BehaviorActed, MailAddr};
136/// struct Sender;
137/// #[behavior::behavior(addr = MailAddr, message = (), sends = { replies: Vec<u8> })]
138/// impl Sender {
139///     fn receive(&mut self, _: MailAddr, _: ()) -> BehaviorActed<Self> {
140///         Ok(Actions::cont().send_replies("not a u8"))
141///     }
142/// }
143/// ```
144///
145/// A child absent from the declared closed birth product cannot be created:
146///
147/// ```compile_fail
148/// use behavior::{Actions, BehaviorActed, Create, MailAddr};
149/// struct Declared;
150/// struct Other;
151/// struct Root;
152/// #[behavior::behavior(addr = MailAddr, message = (), births = { declared: Declared })]
153/// impl Root {
154///     fn receive(&mut self, _: MailAddr, _: ()) -> BehaviorActed<Self> {
155///         Ok(Actions::create(vec![Create::birth(1, Other)]))
156///     }
157/// }
158/// ```
159///
160/// Every generated send lane remains a separate interpreter obligation:
161///
162/// ```compile_fail
163/// use behavior::{BehaviorActed, Delivery, InterpretDelivery, InterpretSends, MailAddr,
164///     MessageProtocol, Recipient, SendInterpreter};
165/// struct Root;
166/// type First = MessageProtocol<MailAddr, u8>;
167/// type Second = MessageProtocol<MailAddr, u16>;
168/// #[behavior::behavior(addr = MailAddr, message = (), sends = {
169///     first: Vec<Delivery<First>>,
170///     second: Vec<Delivery<Second>>,
171/// })]
172/// impl Root {
173///     fn receive(&mut self, _: MailAddr, _: ()) -> BehaviorActed<Self> {
174///         Ok(behavior::Actions::cont())
175///     }
176/// }
177/// struct Incomplete;
178/// impl SendInterpreter for Incomplete { type Error = (); }
179/// impl InterpretDelivery<First> for Incomplete {
180///     fn interpret_delivery(&mut self, _: Delivery<First>) -> impl core::future::Future<Output = Result<(), ()>> + Send {
181///         async { Ok(()) }
182///     }
183/// }
184/// fn require_complete()
185/// where
186///     RootSends: InterpretSends<Incomplete, behavior::User<MailAddr, ()>, behavior::Here>,
187/// {}
188/// ```
189///
190/// Generated child products likewise require an installer for every declared
191/// alternative:
192///
193/// ```compile_fail
194/// use behavior::{BehaviorActed, Create, DispatchBirth, InstallBirth, MailAddr, Never};
195/// struct First;
196/// struct Second;
197/// #[behavior::behavior(addr = MailAddr, message = Never)]
198/// impl First {
199///     fn receive(&mut self, _: MailAddr, message: Never) -> BehaviorActed<Self> { match message {} }
200/// }
201/// #[behavior::behavior(addr = MailAddr, message = Never)]
202/// impl Second {
203///     fn receive(&mut self, _: MailAddr, message: Never) -> BehaviorActed<Self> { match message {} }
204/// }
205/// struct Root;
206/// #[behavior::behavior(addr = MailAddr, message = (), births = {
207///     first: First,
208///     second: Second,
209/// })]
210/// impl Root {
211///     fn receive(&mut self, _: MailAddr, _: ()) -> BehaviorActed<Self> {
212///         Ok(behavior::Actions::cont())
213///     }
214/// }
215/// struct Incomplete;
216/// impl InstallBirth<MailAddr, First, (), Never> for Incomplete {
217///     async fn install_birth(&mut self, _: Create<MailAddr, First>) -> Result<(), Never> { Ok(()) }
218/// }
219/// fn require_complete<T: DispatchBirth<MailAddr, Incomplete, (), Never>>() {}
220/// require_complete::<RootChildren>();
221/// ```
222///
223/// A generated child route accepts only its declared behavior:
224///
225/// ```compile_fail
226/// use behavior::{BehaviorActed, Children, MailAddr, Never};
227/// struct Declared;
228/// #[behavior::behavior(addr = MailAddr, message = Never)]
229/// impl Declared {
230///     fn receive(&mut self, _: MailAddr, message: Never) -> BehaviorActed<Self> {
231///         match message {}
232///     }
233/// }
234/// struct Other;
235/// #[behavior::behavior(addr = MailAddr, message = Never)]
236/// impl Other {
237///     fn receive(&mut self, _: MailAddr, message: Never) -> BehaviorActed<Self> {
238///         match message {}
239///     }
240/// }
241/// struct Root;
242/// #[behavior::behavior(addr = MailAddr, message = Never, births = { worker: Declared })]
243/// impl Root {
244///     fn receive(&mut self, _: MailAddr, message: Never) -> BehaviorActed<Self> {
245///         match message {}
246///     }
247/// }
248/// let routes = RootChildrenRoutes::new(1);
249/// let _ = Children::<MailAddr>::new().child_at(routes.worker, Other);
250/// ```
251///
252/// Two declared roles remain distinct even when they use the same behavior:
253///
254/// ```compile_fail
255/// use behavior::{BehaviorActed, ChildRoute, MailAddr, Never};
256/// struct Worker;
257/// #[behavior::behavior(addr = MailAddr, message = Never)]
258/// impl Worker {
259///     fn receive(&mut self, _: MailAddr, message: Never) -> BehaviorActed<Self> {
260///         match message {}
261///     }
262/// }
263/// struct Root;
264/// #[behavior::behavior(addr = MailAddr, message = Never, births = {
265///     primary: Worker,
266///     backup: Worker,
267/// })]
268/// impl Root {
269///     fn receive(&mut self, _: MailAddr, message: Never) -> BehaviorActed<Self> {
270///         match message {}
271///     }
272/// }
273/// fn requires_primary(_: ChildRoute<Worker, RootChildrenPrimary>) {}
274/// let routes = RootChildrenRoutes::new(1, 2);
275/// requires_primary(routes.backup);
276/// ```
277///
278/// Named topology selectors accept only the child declared for that parent
279/// role, which lets an application builder remain entirely static:
280///
281/// ```compile_fail
282/// use behavior::{Behavior, BehaviorActed, ChildRole, MailAddr, Never};
283/// struct Worker;
284/// #[behavior::behavior(addr = MailAddr, message = Never)]
285/// impl Worker {
286///     fn receive(&mut self, _: MailAddr, message: Never) -> BehaviorActed<Self> {
287///         match message {}
288///     }
289/// }
290/// struct Query;
291/// #[behavior::behavior(addr = MailAddr, message = Never)]
292/// impl Query {
293///     fn receive(&mut self, _: MailAddr, message: Never) -> BehaviorActed<Self> {
294///         match message {}
295///     }
296/// }
297/// struct Root;
298/// #[behavior::behavior(addr = MailAddr, message = Never, births = { workers: Worker })]
299/// impl Root {
300///     fn receive(&mut self, _: MailAddr, message: Never) -> BehaviorActed<Self> {
301///         match message {}
302///     }
303/// }
304/// fn child<Parent, Role>(_: Role, _: Role::Child)
305/// where
306///     Parent: Behavior,
307///     Role: ChildRole<Parent>,
308/// {}
309/// child::<Root, _>(RootChild::Workers, Query);
310/// ```
311pub use behavior_macros::behavior;