1
0
forked from ROMEO/nexosim

Merge pull request #53 from asynchronics/feature/util

Add asynchronix-util crate
This commit is contained in:
Serge Barral 2024-10-31 17:03:51 +01:00 committed by GitHub
commit 06079bd5cd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 104 additions and 1 deletions

View File

@ -1,3 +1,3 @@
[workspace]
members = ["asynchronix"]
members = ["asynchronix", "asynchronix-util"]
resolver = "2"

View File

@ -0,0 +1,7 @@
[package]
name = "asynchronix-util"
version = "0.1.0"
edition = "2021"
[dependencies]
asynchronix = {version = "0.2.2", path = "../asynchronix"}

View File

@ -0,0 +1,3 @@
# Utilities for model-building
TODO: add documentation

View File

@ -0,0 +1 @@
pub mod observables;

View File

@ -0,0 +1,90 @@
use std::ops::Deref;
use asynchronix::ports::Output;
/// Observability trait.
pub trait Observable<T> {
/// Observe the value.
fn observe(&self) -> T;
}
impl<T> Observable<T> for T
where
T: Clone,
{
fn observe(&self) -> Self {
self.clone()
}
}
/// Observable state.
///
/// This object encapsulates state. Every state change is propagated to the
/// output.
#[derive(Debug)]
pub struct ObservableState<S, T>
where
S: Observable<T> + Default,
T: Clone + Send + 'static,
{
/// State.
state: S,
/// Output used for observation.
out: Output<T>,
}
impl<S, T> ObservableState<S, T>
where
S: Observable<T> + Default,
T: Clone + Send + 'static,
{
/// New default state.
pub fn new(out: Output<T>) -> 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<F, R>(&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
}
/// Propagate value.
pub async fn propagate(&mut self) {
self.out.send(self.state.observe()).await;
}
}
impl<S, T> Deref for ObservableState<S, T>
where
S: Observable<T> + Default,
T: Clone + Send + 'static,
{
type Target = S;
fn deref(&self) -> &S {
&self.state
}
}
/// Observable value.
pub type ObservableValue<T> = ObservableState<T, T>;

View File

@ -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