Skip to content

Commit 0943788

Browse files
committed
Added Reactive trait, bumped to 0.6.0
1 parent 365d8d1 commit 0943788

File tree

16 files changed

+158
-21
lines changed

16 files changed

+158
-21
lines changed

CHANGES.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
<!-- markdownlint-configure-file { "no-duplicate-heading": { "siblings_only": true } } -->
22

33
<!-- markdownlint-disable-next-line first-line-h1 -->
4-
## Unreleased
4+
## 0.6.0 Unreleased
55

66
### Added
77

8+
* `Reactive` trait that allows generic components to be more flexible with props
89
* `BTreeMap` and `chrono::DateTime<Utc>` support in `AutoJsJson`
910
* `#[js_json(default = "None")]` attribute to `AutoJsJson`
1011
* All http methods in `FetchMethod`

crates/vertigo-cli/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "vertigo-cli"
3-
version = "0.5.0"
3+
version = "0.6.0"
44
authors = ["Grzegorz Szeliga <szeligagrzegorz@gmail.com>", "Michał Pokrywka <wolfmoon@o2.pl>"]
55
description = "Reactive Real-DOM library with SSR for Rust - packaging/serving tool"
66
categories = ["command-line-utilities", "development-tools", "development-tools::build-utils", "wasm", "web-programming"]
@@ -39,4 +39,4 @@ tokio-stream = "0.1"
3939
tower-http = { version = "0.4", features = ["fs"] }
4040
tokio-retry = "0.3"
4141
wasmtime = "19.0"
42-
vertigo = { path = "../vertigo", version = "0.5.0" }
42+
vertigo = { path = "../vertigo", version = "0.6.0" }

crates/vertigo-macro/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "vertigo-macro"
3-
version = "0.5.0"
3+
version = "0.6.0"
44
authors = ["Grzegorz Szeliga <szeligagrzegorz@gmail.com>", "Michał Pokrywka <wolfmoon@o2.pl>"]
55
description = "Reactive Real-DOM library with SSR for Rust - macros"
66
edition = "2021"

crates/vertigo/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "vertigo"
3-
version = "0.5.0"
3+
version = "0.6.0"
44
authors = ["Grzegorz Szeliga <szeligagrzegorz@gmail.com>", "Michał Pokrywka <wolfmoon@o2.pl>"]
55
description = "Reactive Real-DOM library with SSR for Rust"
66
readme = "README.md"
@@ -15,4 +15,4 @@ edition = "2021"
1515
[dependencies]
1616
chrono = { version = "0.4", default-features = false, features = ["std"], optional = true }
1717
log = { version = "0.4", features = ["std"] }
18-
vertigo-macro = { path = "../../crates/vertigo-macro", version = "0.5.0" }
18+
vertigo-macro = { path = "../../crates/vertigo-macro", version = "0.6.0" }

crates/vertigo/src/computed/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ mod dependencies;
55
mod drop_resource;
66
mod graph_id;
77
mod graph_value;
8+
mod reactive;
89
pub mod struct_mut;
910
mod value;
1011

@@ -17,6 +18,7 @@ pub use dependencies::Dependencies;
1718
pub use drop_resource::DropResource;
1819
pub use graph_id::GraphId;
1920
pub use graph_value::GraphValue;
21+
pub use reactive::Reactive;
2022
pub use value::Value;
2123

2224
/// Allows to create `Computed<T1, T2, ...>` out of `Value<T1>`, `Value<T2>`, ...
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
use crate::{Context, Value};
2+
3+
/// A trait that tells `Something<T>` is behaving like a [`Value<T>`].
4+
///
5+
/// Generic components should accept [`Reactive<T>`] instead of [`Value<T>`] to be more flexible,
6+
/// so that types wrapping a Value can implement Reactive and be used in those components.
7+
///
8+
/// Automatically implemented for the [Value] itself.
9+
///
10+
/// Example:
11+
///
12+
/// ```rust
13+
/// use vertigo::{component, EmbedDom, Computed, Context, dom, DomNode, Reactive, Value, transaction};
14+
///
15+
/// // Define reactive object with `Value` wrapped
16+
/// #[derive(Clone, PartialEq)]
17+
/// struct Lisper {
18+
/// inner: Value<String>
19+
/// }
20+
///
21+
/// // Implement `EmbedDom` so it can be easily rendered
22+
/// impl EmbedDom for Lisper {
23+
/// fn embed(self) -> DomNode {
24+
/// self.inner.embed()
25+
/// }
26+
/// }
27+
///
28+
/// // Implement `Reactive`
29+
/// impl Reactive<String> for Lisper {
30+
/// fn set(&self, val: String) {
31+
/// let lisp = val.replace('r', "w");
32+
/// self.inner.set(lisp)
33+
/// }
34+
///
35+
/// fn get(&self, ctx: &Context) -> std::string::String {
36+
/// self.inner.get(ctx)
37+
/// }
38+
///
39+
/// fn change(&self, change_fn: impl FnOnce(&mut String)) {
40+
/// self.inner.change(|val| {
41+
/// change_fn(val);
42+
/// *val = val.replace('r', "w");
43+
/// });
44+
/// }
45+
/// }
46+
///
47+
/// // Exemplary generic component
48+
/// #[component]
49+
/// fn Print<R>(saying: R)
50+
/// where
51+
/// R: Reactive<String> + EmbedDom
52+
/// {
53+
/// dom! {
54+
/// <quote>{saying}</quote>
55+
/// }
56+
/// }
57+
///
58+
/// // Create reactive object
59+
/// let lisper = Lisper {
60+
/// inner: Value::new("".to_string())
61+
/// };
62+
///
63+
/// // Specialize Print component
64+
/// type PrintL = Print::<Lisper>;
65+
///
66+
/// // Use reactive object in generic component
67+
/// let _ = dom! {
68+
/// <div>
69+
/// <PrintL saying={lisper.clone()} />
70+
/// </div>
71+
/// };
72+
///
73+
/// lisper.set("Eating raisins and radishes".to_string());
74+
///
75+
/// transaction(|context| {
76+
/// assert_eq!(lisper.get(context), "Eating waisins and wadishes");
77+
/// })
78+
/// ```
79+
pub trait Reactive<T>: PartialEq {
80+
fn set(&self, value: T);
81+
fn get(&self, context: &Context) -> T;
82+
fn change(&self, change_fn: impl FnOnce(&mut T));
83+
}
84+
85+
impl<T> Reactive<T> for Value<T>
86+
where
87+
T: Clone + PartialEq + 'static
88+
{
89+
fn set(&self, value: T) {
90+
Value::set(self, value)
91+
}
92+
93+
fn get(&self, context: &Context) -> T {
94+
Value::get(self, context)
95+
}
96+
97+
fn change(&self, change_fn: impl FnOnce(&mut T)) {
98+
Value::change(self, change_fn)
99+
}
100+
}

crates/vertigo/src/computed/value.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ impl<T: PartialEq> PartialEq for Value<T> {
6464
}
6565

6666
impl<T: Clone + 'static> Value<T> {
67-
pub fn new(value: T) -> Value<T> {
67+
pub fn new(value: T) -> Self {
6868
let deps = get_driver().inner.dependencies;
6969
Value {
7070
inner: Rc::new(ValueInner {

crates/vertigo/src/driver_module/src_js/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { WasmModule } from "./wasm_module";
22

33
// vertigo-cli compatibility version, change together with package version.
44
const VERTIGO_COMPAT_VERSION_MAJOR = 0;
5-
const VERTIGO_COMPAT_VERSION_MINOR = 5;
5+
const VERTIGO_COMPAT_VERSION_MINOR = 6;
66

77
const moduleRun: Set<string> = new Set();
88

crates/vertigo/src/driver_module/wasm_run.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1978,7 +1978,7 @@ class WasmModule {
19781978

19791979
// vertigo-cli compatibility version, change together with package version.
19801980
const VERTIGO_COMPAT_VERSION_MAJOR = 0;
1981-
const VERTIGO_COMPAT_VERSION_MINOR = 5;
1981+
const VERTIGO_COMPAT_VERSION_MINOR = 6;
19821982
const moduleRun = new Set();
19831983
const runModule = async (wasm) => {
19841984
if (moduleRun.has(wasm)) {

crates/vertigo/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ mod websocket;
116116
use computed::struct_mut::ValueMut;
117117

118118
pub use computed::{
119-
context::Context, struct_mut, AutoMap, Computed, Dependencies, DropResource, GraphId,
119+
context::Context, struct_mut, AutoMap, Computed, Dependencies, DropResource, GraphId, Reactive,
120120
ToComputed, Value,
121121
};
122122

crates/vertigo/src/router.rs

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
use crate::{computed::Value, get_driver, Computed};
1+
use crate::{computed::Value, get_driver, Computed, DomNode, EmbedDom, Reactive, ToComputed};
22

33
/// Router based on hash part of current location.
44
///
55
/// ```rust
6-
/// use vertigo::{dom, Computed, Value, DomNode};
6+
/// use vertigo::{dom, Computed, Reactive, Value, DomNode};
77
/// use vertigo::router::Router;
88
///
99
/// #[derive(Clone, PartialEq, Debug)]
@@ -115,4 +115,38 @@ impl<T: Clone + ToString + From<String> + PartialEq + 'static> Router<T> {
115115
true => driver.inner.api.push_history_location(&route.to_string()),
116116
};
117117
}
118+
119+
fn change(&self, change_fn: impl FnOnce(&mut T)) {
120+
get_driver().inner.dependencies.transaction(|ctx| {
121+
let mut value = self.get(ctx);
122+
change_fn(&mut value);
123+
self.set(value);
124+
});
125+
}
126+
}
127+
128+
impl<T: Clone + PartialEq + ToString + From<String>> Reactive<T> for Router<T> {
129+
fn set(&self, value: T) {
130+
Router::set(self, value)
131+
}
132+
133+
fn get(&self, context: &crate::Context) -> T {
134+
self.route.get(context)
135+
}
136+
137+
fn change(&self, change_fn: impl FnOnce(&mut T)) {
138+
Router::change(self, change_fn)
139+
}
140+
}
141+
142+
impl<T: Clone + PartialEq + ToString + From<String>> ToComputed<T> for Router<T> {
143+
fn to_computed(&self) -> Computed<T> {
144+
self.route.to_computed()
145+
}
146+
}
147+
148+
impl<T: Clone + PartialEq + ToString + From<String>> EmbedDom for Router<T> {
149+
fn embed(self) -> DomNode {
150+
self.route.embed()
151+
}
118152
}

demo/app/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "vertigo-demo"
3-
version = "0.5.0"
3+
version = "0.6.0"
44
authors = ["Grzegorz Szeliga <szeligagrzegorz@gmail.com>", "Michał Pokrywka <wolfmoon@o2.pl>"]
55
edition = "2021"
66

@@ -9,4 +9,4 @@ crate-type = ["cdylib", "rlib"]
99

1010
[dependencies]
1111
log = "0.4.17"
12-
vertigo = { path = "../../crates/vertigo", version = "0.5.0" }
12+
vertigo = { path = "../../crates/vertigo", version = "0.6.0" }

examples/counter/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
[package]
22
name = "vertigo-example-counter"
3-
version = "0.5.0"
3+
version = "0.6.0"
44
authors = ["Grzegorz Szeliga <szeligagrzegorz@gmail.com>", "Michał Pokrywka <wolfmoon@o2.pl>"]
55
edition = "2021"
66

77
[lib]
88
crate-type = ["cdylib", "rlib"]
99

1010
[dependencies]
11-
vertigo = { path = "../../crates/vertigo", version = "0.5.0" }
11+
vertigo = { path = "../../crates/vertigo", version = "0.6.0" }

examples/router/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "vertigo-example-router"
3-
version = "0.5.0"
3+
version = "0.6.0"
44
authors = ["Grzegorz Szeliga <szeligagrzegorz@gmail.com>", "Michał Pokrywka <wolfmoon@o2.pl>"]
55
edition = "2021"
66

@@ -9,4 +9,4 @@ crate-type = ["cdylib", "rlib"]
99

1010
[dependencies]
1111
log = "0.4.14"
12-
vertigo = { path = "../../crates/vertigo", version = "0.5.0" }
12+
vertigo = { path = "../../crates/vertigo", version = "0.6.0" }

examples/trafficlights/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
[package]
22
name = "vertigo-example-trafficlights"
3-
version = "0.5.0"
3+
version = "0.6.0"
44
authors = ["Grzegorz Szeliga <szeligagrzegorz@gmail.com>", "Michał Pokrywka <wolfmoon@o2.pl>"]
55
edition = "2021"
66

77
[lib]
88
crate-type = ["cdylib", "rlib"]
99

1010
[dependencies]
11-
vertigo = { path = "../../crates/vertigo", version = "0.5.0" }
11+
vertigo = { path = "../../crates/vertigo", version = "0.6.0" }

tutorial.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<!-- markdownlint-disable no-inline-html -->
33

44
<!-- markdownlint-disable-next-line no-emphasis-as-heading -->
5-
*Up to date with version 0.5.0*
5+
*Up to date with version 0.6.0*
66

77
<!-- markdownlint-disable-next-line heading-increment -->
88
### Table of contents

0 commit comments

Comments
 (0)