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;