From 63c46a6d8d31394e74bde83cf5334f8b7cec9326 Mon Sep 17 00:00:00 2001 From: huntc Date: Tue, 14 Nov 2023 10:23:51 +1100 Subject: [PATCH] More Effect doc --- akka-persistence-rs/src/effect.rs | 74 +++++++++++++++++++++++++++---- akka-persistence-rs/src/jdk.rs | 2 +- 2 files changed, 67 insertions(+), 9 deletions(-) diff --git a/akka-persistence-rs/src/effect.rs b/akka-persistence-rs/src/effect.rs index 8e3836f..9ef94ba 100644 --- a/akka-persistence-rs/src/effect.rs +++ b/akka-persistence-rs/src/effect.rs @@ -1,16 +1,74 @@ -//! Effects that are lazily performed as a result of performing a command -//! of an entity. Effects can be chained with other effects and are guaranteed +//! Effects express how the state of an entity is to be updated, and how various side-effects +//! can be performed; all in response to an entity's commands. Effects can be chained with other effects and are guaranteed //! to be applied (run) before the next command for an entity id is processed. //! -//! Convience methods are providing for commonly chained operations, and take -//! the form of `and_then` and `then` as the prefix. By Rust convention, `and_then` +//! Effects are applied +//! on being returned from a command handler. Command handlers are "pure" and deliberately constrained +//! from performing side effects. Using effects this way helps us reason the code of a command handler, and facilitate testing +//! outside of running an entity manager. +//! +//! An example as used within a command handler: +//! +//! ```no_run +//! use akka_persistence_rs::effect::{EffectExt, persist_event}; +//! +//! // ... +//! # struct SomeEvent; +//! # let (reply_to, _) = tokio::sync::oneshot::channel(); +//! # let reply_value = 1; +//! # struct MyBehavior; +//! # let persist_event = persist_event::; +//! # impl akka_persistence_rs::entity::EventSourcedBehavior for MyBehavior { +//! # type State = (); +//! # type Command = (); +//! # type Event = SomeEvent; +//! # fn for_command(_: &akka_persistence_rs::entity::Context, _: &Self::State, _: Self::Command) -> Box> {todo!()} +//! # fn on_event(_: &akka_persistence_rs::entity::Context, _: &mut Self::State, _: Self::Event) {todo!()} +//! # } +//! +//! persist_event(SomeEvent) +//! .then_reply(move |_s| Some((reply_to, reply_value))) +//! .boxed(); +//! ``` +//! +//! Convenience methods are provided for commonly chained operations and often provide any state that +//! has been updated by a previous operation. +//! These conveniences take the form of `and_then` and `then` as the prefix. By Rust convention, `and_then` //! provides the result of the previous operation and expects a result provided //! given some closure. Also by convention, `then` is applied only when the previous operation //! completed successfully. //! -//! In the case where there is no convenience method, a generalized `and` -//! operation can be used to chain any effect found here, or a customized -//! effect. +//! The [EffectExt::boxed] method is a convenience for "boxing" the chain of effects into a concrete +//! type that can be returned from a command handler. For more information on boxing, please refer +//! to [the Rust documentation](https://doc.rust-lang.org/std/boxed/index.html). +//! +//! Custom effects may also be provided by implementing the [Effect] and [EffectExt] +//! traits. See the [Reply] type to illustrate how. +//! +//! In the case where there is no convenience method, such as with custom ones, a generalized `and` +//! operation can be used to chain any effect. Using the previous `then_reply` example: +//! +//! ```no_run +//! use akka_persistence_rs::effect::{EffectExt, reply, persist_event}; +//! +//! // ... +//! # struct SomeEvent; +//! # let (reply_to, _) = tokio::sync::oneshot::channel(); +//! # let reply_value = 1; +//! # struct MyBehavior; +//! # let persist_event = persist_event::; +//! # impl akka_persistence_rs::entity::EventSourcedBehavior for MyBehavior { +//! # type State = (); +//! # type Command = (); +//! # type Event = SomeEvent; +//! # fn for_command(_: &akka_persistence_rs::entity::Context, _: &Self::State, _: Self::Command) -> Box> {todo!()} +//! # fn on_event(_: &akka_persistence_rs::entity::Context, _: &mut Self::State, _: Self::Event) {todo!()} +//! # } +//! +//! persist_event(SomeEvent) +//! .and(reply(reply_to, reply_value)) +//! .boxed(); +//! ``` use async_trait::async_trait; use chrono::Utc; @@ -494,7 +552,7 @@ where { } -/// The return type of [EffectExt::and_then_reply]. +/// The return type of [EffectExt::then_reply]. pub struct ThenReply { f: Option, phantom: PhantomData<(B, R, T)>, diff --git a/akka-persistence-rs/src/jdk.rs b/akka-persistence-rs/src/jdk.rs index 668595f..9c03e8c 100644 --- a/akka-persistence-rs/src/jdk.rs +++ b/akka-persistence-rs/src/jdk.rs @@ -4,7 +4,7 @@ use std::{ }; /// A hasher for hashing strings conformant with -/// https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#hashCode. +/// . /// Undefined hash values will be produced if anything but a /// Rust [String] is hashed. pub struct StringHasher;