forked from ROMEO/nexosim
Merge pull request #53 from asynchronics/feature/util
Add asynchronix-util crate
This commit is contained in:
commit
06079bd5cd
@ -1,3 +1,3 @@
|
||||
[workspace]
|
||||
members = ["asynchronix"]
|
||||
members = ["asynchronix", "asynchronix-util"]
|
||||
resolver = "2"
|
||||
|
7
asynchronix-util/Cargo.toml
Normal file
7
asynchronix-util/Cargo.toml
Normal file
@ -0,0 +1,7 @@
|
||||
[package]
|
||||
name = "asynchronix-util"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
asynchronix = {version = "0.2.2", path = "../asynchronix"}
|
3
asynchronix-util/README.md
Normal file
3
asynchronix-util/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
# Utilities for model-building
|
||||
|
||||
TODO: add documentation
|
1
asynchronix-util/src/lib.rs
Normal file
1
asynchronix-util/src/lib.rs
Normal file
@ -0,0 +1 @@
|
||||
pub mod observables;
|
90
asynchronix-util/src/observables.rs
Normal file
90
asynchronix-util/src/observables.rs
Normal 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>;
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user