From 634614a2a152835742078120b5c102c759f657e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ja=C5=ADhien=20Piatlicki?= Date: Thu, 31 Oct 2024 14:11:25 +0100 Subject: [PATCH 1/3] Add observable states utility --- Cargo.toml | 2 +- asynchronix-util/Cargo.toml | 7 +++ asynchronix-util/src/lib.rs | 1 + asynchronix-util/src/observables.rs | 85 +++++++++++++++++++++++++++++ asynchronix/Cargo.toml | 2 + 5 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 asynchronix-util/Cargo.toml create mode 100644 asynchronix-util/src/lib.rs create mode 100644 asynchronix-util/src/observables.rs diff --git a/Cargo.toml b/Cargo.toml index c24bd10..6894a12 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,3 @@ [workspace] -members = ["asynchronix"] +members = ["asynchronix", "asynchronix-util"] resolver = "2" diff --git a/asynchronix-util/Cargo.toml b/asynchronix-util/Cargo.toml new file mode 100644 index 0000000..af5f158 --- /dev/null +++ b/asynchronix-util/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "asynchronix-util" +version = "0.1.0" +edition = "2021" + +[dependencies] +asynchronix = {version = "0.2.2", path = "../asynchronix"} diff --git a/asynchronix-util/src/lib.rs b/asynchronix-util/src/lib.rs new file mode 100644 index 0000000..4010ef7 --- /dev/null +++ b/asynchronix-util/src/lib.rs @@ -0,0 +1 @@ +pub mod observables; diff --git a/asynchronix-util/src/observables.rs b/asynchronix-util/src/observables.rs new file mode 100644 index 0000000..1adefa0 --- /dev/null +++ b/asynchronix-util/src/observables.rs @@ -0,0 +1,85 @@ +use std::ops::Deref; + +use asynchronix::ports::Output; + +/// Observability trait. +pub trait Observable { + /// Observe the value. + fn observe(&self) -> T; +} + +impl Observable for T +where + T: Clone, +{ + fn observe(&self) -> Self { + self.clone() + } +} + +/// Observable state. +/// +/// This struct incapsulates state. Every state change is propagated to the +/// output. +#[derive(Debug)] +pub struct ObservableState +where + S: Observable + Default, + T: Clone + Send + 'static, +{ + /// State. + state: S, + + /// Output used for observation. + out: Output, +} + +impl ObservableState +where + S: Observable + Default, + T: Clone + Send + 'static, +{ + /// New default state. + pub fn new(out: Output) -> Self { + Self { + state: S::default(), + out, + } + } + + /// Get state. + pub fn get(&self) -> &S { + &self.state + } + + /// Set state. + pub async fn set(&mut self, value: S) { + self.state = value; + self.out.send(self.state.observe()).await; + } + + /// Modify state using mutable reference. + pub async fn modify(&mut self, f: F) -> R + where + F: FnOnce(&mut S) -> R, + { + let r = f(&mut self.state); + self.out.send(self.state.observe()).await; + r + } +} + +impl Deref for ObservableState +where + S: Observable + Default, + T: Clone + Send + 'static, +{ + type Target = S; + + fn deref(&self) -> &S { + &self.state + } +} + +/// Observable value. +pub type ObservableValue = ObservableState; diff --git a/asynchronix/Cargo.toml b/asynchronix/Cargo.toml index 5f30507..a5eee42 100644 --- a/asynchronix/Cargo.toml +++ b/asynchronix/Cargo.toml @@ -4,6 +4,8 @@ name = "asynchronix" # - Update crate version in this Cargo.toml # - Update crate version in README.md # - Update crate version in the lib.rs documentation of feature flags +# - Update dependency in sibling crates +# - Remove path dependencies # - Update CHANGELOG.md # - Update if necessary copyright notice in LICENSE-MIT # - Create a "vX.Y.Z" git tag From 087f3c84cc17048e6448d1f6560ec4333a873cd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ja=C5=ADhien=20Piatlicki?= Date: Thu, 31 Oct 2024 14:51:33 +0100 Subject: [PATCH 2/3] Add README to asynchronix-util --- asynchronix-util/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 asynchronix-util/README.md diff --git a/asynchronix-util/README.md b/asynchronix-util/README.md new file mode 100644 index 0000000..4bdbc8d --- /dev/null +++ b/asynchronix-util/README.md @@ -0,0 +1,3 @@ +# Utilities for model-building + +TODO: add documentation From 0732a7ef54db62194adece5eb6e9efb07b923257 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ja=C5=ADhien=20Piatlicki?= Date: Thu, 31 Oct 2024 15:59:35 +0100 Subject: [PATCH 3/3] Changes after review --- asynchronix-util/src/observables.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/asynchronix-util/src/observables.rs b/asynchronix-util/src/observables.rs index 1adefa0..45bb28a 100644 --- a/asynchronix-util/src/observables.rs +++ b/asynchronix-util/src/observables.rs @@ -19,7 +19,7 @@ where /// Observable state. /// -/// This struct incapsulates state. Every state change is propagated to the +/// This object encapsulates state. Every state change is propagated to the /// output. #[derive(Debug)] pub struct ObservableState @@ -67,6 +67,11 @@ where self.out.send(self.state.observe()).await; r } + + /// Propagate value. + pub async fn propagate(&mut self) { + self.out.send(self.state.observe()).await; + } } impl Deref for ObservableState