Skip to content

Commit fd0ba42

Browse files
committed
feat!: DomToken's csr state doesn't require Default
1 parent 6b9c96f commit fd0ba42

File tree

11 files changed

+293
-155
lines changed

11 files changed

+293
-155
lines changed

packages/frender-dom-tokens/src/chain.rs

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use frender_const::{ConstUsize, KnownConstUsizeAdd};
33
use crate::{
44
constness::{HasConstKnownPossibleDomTokens, IsConstUsize},
55
dom_token::UniqueDomTokenArrayVec,
6-
ChainableDomTokens, DomTokens,
6+
ChainableDomTokens, DomTokens, DomTokensStateUnmount,
77
};
88

99
#[derive(Debug, Clone, Copy)]
@@ -24,29 +24,51 @@ where
2424
};
2525
}
2626

27+
impl<A: DomTokensStateUnmount, B: DomTokensStateUnmount> DomTokensStateUnmount for (A, B) {
28+
fn dom_tokens_state_unmount(
29+
(state_a, state_b): &mut Self,
30+
dom_token_list: &mut impl crate::DomTokenList,
31+
) {
32+
A::dom_tokens_state_unmount(state_a, dom_token_list);
33+
B::dom_tokens_state_unmount(state_b, dom_token_list);
34+
}
35+
}
36+
2737
impl<A: ChainableDomTokens, B: ChainableDomTokens> DomTokens for Chain<A, B>
2838
where
2939
Self: HasConstKnownPossibleDomTokens,
3040
{
31-
type UpdateWithState = (A::UpdateWithState, B::UpdateWithState);
41+
type State = (A::State, B::State);
42+
43+
fn dom_tokens_render_init(
44+
Self(a, b): Self,
45+
dom_token_list: &mut impl crate::DomTokenList,
46+
) -> Self::State {
47+
_ = Self::ASSERT_KNOWN_NOT_DUP;
48+
(
49+
A::dom_tokens_render_init(a, dom_token_list),
50+
B::dom_tokens_render_init(b, dom_token_list),
51+
)
52+
}
3253

33-
fn update_with_state(
54+
fn dom_tokens_render_init_with_old_state(
3455
Self(a, b): Self,
3556
dom_token_list: &mut impl crate::DomTokenList,
36-
(state_a, state_b): &mut Self::UpdateWithState,
57+
(old_state_a, old_state_b): &mut Self::State,
3758
) {
3859
_ = Self::ASSERT_KNOWN_NOT_DUP;
39-
A::update_with_state(a, dom_token_list, state_a);
40-
B::update_with_state(b, dom_token_list, state_b);
60+
A::dom_tokens_render_init_with_old_state(a, dom_token_list, old_state_a);
61+
B::dom_tokens_render_init_with_old_state(b, dom_token_list, old_state_b);
4162
}
4263

43-
fn remove_with_state(
64+
fn dom_tokens_render_update(
65+
Self(a, b): Self,
4466
dom_token_list: &mut impl crate::DomTokenList,
45-
(state_a, state_b): &mut Self::UpdateWithState,
67+
(state_a, state_b): &mut Self::State,
4668
) {
4769
_ = Self::ASSERT_KNOWN_NOT_DUP;
48-
A::remove_with_state(dom_token_list, state_a);
49-
B::remove_with_state(dom_token_list, state_b);
70+
A::dom_tokens_render_update(a, dom_token_list, state_a);
71+
B::dom_tokens_render_update(b, dom_token_list, state_b);
5072
}
5173

5274
type DomTokensIntoAsyncStrIter = async_str_iter::chain::Chain<

packages/frender-dom-tokens/src/constness.rs

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1+
use std::marker::PhantomData;
2+
3+
use csr::State;
14
pub use frender_const::ConstUsize;
25

36
use frender_common::const_utils::put_at;
47

58
use crate::{
6-
dom_token::UniqueDomTokenArrayVec, ChainableDomTokens, DomToken, DomTokens, UniqueDomTokenArray,
9+
dom_token::UniqueDomTokenArrayVec, ChainableDomTokens, DomToken, DomTokens,
10+
DomTokensStateUnmount, UniqueDomTokenArray,
711
};
812

913
mod sealed {
@@ -192,35 +196,42 @@ pub mod ssr {
192196
}
193197
}
194198

199+
pub mod csr {
200+
use std::marker::PhantomData;
201+
202+
use crate::DomTokensStateUnmount;
203+
204+
use super::HasConstDomTokens;
205+
206+
pub struct State<T: ?Sized + HasConstDomTokens>(pub(super) PhantomData<T>);
207+
208+
impl<T: ?Sized + HasConstDomTokens> DomTokensStateUnmount for State<T> {
209+
fn dom_tokens_state_unmount(_: &mut Self, dom_token_list: &mut impl crate::DomTokenList) {
210+
T::DOM_TOKENS
211+
.as_ref()
212+
.iter()
213+
.for_each(|t| dom_token_list.remove_1(*t))
214+
}
215+
}
216+
}
217+
195218
impl<T: ?Sized + HasConstDomTokens> DomTokens for ConstDomTokens<T> {
196-
type UpdateWithState = bool; // whether updated
219+
type State = State<T>;
197220

198-
fn update_with_state(
221+
fn dom_tokens_render_init(
199222
_: Self,
200223
dom_token_list: &mut impl crate::DomTokenList,
201-
state: &mut Self::UpdateWithState,
202-
) {
203-
if *state {
204-
return;
205-
}
206-
*state = true;
224+
) -> Self::State {
207225
T::DOM_TOKENS
208226
.as_ref()
209227
.iter()
210-
.for_each(|t| dom_token_list.add_1(*t))
228+
.for_each(|t| dom_token_list.add_1(*t));
229+
230+
State(PhantomData)
211231
}
212232

213-
fn remove_with_state(
214-
dom_token_list: &mut impl crate::DomTokenList,
215-
state: &mut Self::UpdateWithState,
216-
) {
217-
if *state {
218-
*state = false;
219-
T::DOM_TOKENS
220-
.as_ref()
221-
.iter()
222-
.for_each(|t| dom_token_list.remove_1(*t))
223-
}
233+
fn dom_tokens_render_update(_: Self, _: &mut impl crate::DomTokenList, _: &mut Self::State) {
234+
// Does nothing
224235
}
225236

226237
type DomTokensIntoAsyncStrIter = ssr::ConstDomTokensIntoAsyncStrIter<T>;

packages/frender-dom-tokens/src/either.rs

Lines changed: 72 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
use async_str_iter::either::IterEither;
2-
use frender_common::either::EitherState;
2+
use csr::State;
33
use frender_const::{ConstUsize, KnownConstUsizeAdd};
44

55
use crate::{
66
constness::{HasConstKnownPossibleDomTokens, IsConstUsize},
77
dom_token::UniqueDomTokenArrayVec,
8-
ChainableDomTokens, DomTokens,
8+
ChainableDomTokens, DomTokens, DomTokensStateUnmount,
99
};
1010

1111
#[derive(Debug, Clone, Copy)]
@@ -14,47 +14,87 @@ pub enum EitherDomTokens<A, B> {
1414
B(B),
1515
}
1616

17+
pub mod csr {
18+
use crate::DomTokensStateUnmount;
19+
20+
pub enum State<A, B> {
21+
A(A),
22+
B(B),
23+
}
24+
25+
impl<A: DomTokensStateUnmount, B: DomTokensStateUnmount> DomTokensStateUnmount for State<A, B> {
26+
fn dom_tokens_state_unmount(
27+
state: &mut Self,
28+
dom_token_list: &mut impl crate::DomTokenList,
29+
) {
30+
match state {
31+
State::A(state) => A::dom_tokens_state_unmount(state, dom_token_list),
32+
State::B(state) => B::dom_tokens_state_unmount(state, dom_token_list),
33+
}
34+
}
35+
}
36+
}
37+
1738
impl<L: DomTokens, R: DomTokens> DomTokens for EitherDomTokens<L, R> {
18-
type UpdateWithState = EitherState<L::UpdateWithState, R::UpdateWithState>;
39+
type State = State<L::State, R::State>;
40+
41+
fn dom_tokens_render_init(
42+
this: Self,
43+
dom_token_list: &mut impl crate::DomTokenList,
44+
) -> Self::State {
45+
match this {
46+
EitherDomTokens::A(this) => State::A(L::dom_tokens_render_init(this, dom_token_list)),
47+
EitherDomTokens::B(this) => State::B(R::dom_tokens_render_init(this, dom_token_list)),
48+
}
49+
}
1950

20-
fn update_with_state(
51+
fn dom_tokens_render_init_with_old_state(
2152
this: Self,
2253
dom_token_list: &mut impl crate::DomTokenList,
23-
state: &mut Self::UpdateWithState,
54+
old_state: &mut Self::State,
2455
) {
2556
match this {
26-
EitherDomTokens::A(this) => {
27-
let state = match state {
28-
EitherState::Left { inner: state } => state,
29-
EitherState::Right { inner: old_state } => {
30-
R::remove_with_state(dom_token_list, old_state);
31-
state.get_left_or_insert_default()
32-
}
33-
};
34-
35-
L::update_with_state(this, dom_token_list, state)
36-
}
37-
EitherDomTokens::B(this) => {
38-
let state = match state {
39-
EitherState::Right { inner: state } => state,
40-
EitherState::Left { inner: old_state } => {
41-
L::remove_with_state(dom_token_list, old_state);
42-
state.get_right_or_insert_default()
43-
}
44-
};
45-
46-
R::update_with_state(this, dom_token_list, state)
47-
}
57+
EitherDomTokens::A(this) => match old_state {
58+
State::A(old_state) => {
59+
L::dom_tokens_render_init_with_old_state(this, dom_token_list, old_state)
60+
}
61+
State::B(_) => {
62+
// Already unmounted
63+
*old_state = State::A(L::dom_tokens_render_init(this, dom_token_list))
64+
}
65+
},
66+
EitherDomTokens::B(this) => match old_state {
67+
State::B(old_state) => {
68+
R::dom_tokens_render_init_with_old_state(this, dom_token_list, old_state)
69+
}
70+
State::A(_) => {
71+
// Already unmounted
72+
*old_state = State::B(R::dom_tokens_render_init(this, dom_token_list))
73+
}
74+
},
4875
}
4976
}
5077

51-
fn remove_with_state(
78+
fn dom_tokens_render_update(
79+
this: Self,
5280
dom_token_list: &mut impl crate::DomTokenList,
53-
state: &mut Self::UpdateWithState,
81+
state: &mut Self::State,
5482
) {
55-
match state {
56-
EitherState::Left { inner: state } => L::remove_with_state(dom_token_list, state),
57-
EitherState::Right { inner: state } => R::remove_with_state(dom_token_list, state),
83+
match this {
84+
EitherDomTokens::A(this) => match state {
85+
State::A(state) => L::dom_tokens_render_update(this, dom_token_list, state),
86+
State::B(old_state) => {
87+
<R::State>::dom_tokens_state_unmount(old_state, dom_token_list);
88+
*state = State::A(L::dom_tokens_render_init(this, dom_token_list))
89+
}
90+
},
91+
EitherDomTokens::B(this) => match state {
92+
State::B(state) => R::dom_tokens_render_update(this, dom_token_list, state),
93+
State::A(old_state) => {
94+
<L::State>::dom_tokens_state_unmount(old_state, dom_token_list);
95+
*state = State::B(R::dom_tokens_render_init(this, dom_token_list))
96+
}
97+
},
5898
}
5999
}
60100

packages/frender-dom-tokens/src/empty.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,31 @@ use frender_const::ConstUsize;
44

55
use crate::{
66
constness::HasConstKnownPossibleDomTokens, dom_token::UniqueDomTokenArrayVec,
7-
ChainableDomTokens, DomTokens,
7+
ChainableDomTokens, DomTokens, DomTokensStateUnmount,
88
};
99

10+
impl DomTokensStateUnmount for () {
11+
fn dom_tokens_state_unmount((): &mut Self, _: &mut impl crate::DomTokenList) {}
12+
}
13+
1014
impl DomTokens for Empty {
11-
type UpdateWithState = ();
15+
type State = ();
1216

13-
fn update_with_state(
17+
fn dom_tokens_render_init(Self: Self, _: &mut impl crate::DomTokenList) -> Self::State {}
18+
19+
fn dom_tokens_render_init_with_old_state(
1420
Self: Self,
1521
_: &mut impl crate::DomTokenList,
16-
(): &mut Self::UpdateWithState,
22+
(): &mut Self::State,
1723
) {
1824
}
1925

20-
fn remove_with_state(_: &mut impl crate::DomTokenList, (): &mut Self::UpdateWithState) {}
26+
fn dom_tokens_render_update(
27+
Self: Self,
28+
_: &mut impl crate::DomTokenList,
29+
(): &mut Self::State,
30+
) {
31+
}
2132

2233
type DomTokensIntoAsyncStrIter = async_str_iter::empty::Empty;
2334

packages/frender-dom-tokens/src/erase_const_known.rs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,29 @@ use crate::{
1212
pub struct EraseConstKnownPossibleDomTokens<T>(pub T);
1313

1414
impl<T: DomTokens> DomTokens for EraseConstKnownPossibleDomTokens<T> {
15-
type UpdateWithState = T::UpdateWithState;
15+
type State = T::State;
1616

17-
fn update_with_state(
18-
this: Self,
17+
fn dom_tokens_render_init(
18+
Self(this): Self,
19+
dom_token_list: &mut impl crate::DomTokenList,
20+
) -> Self::State {
21+
T::dom_tokens_render_init(this, dom_token_list)
22+
}
23+
24+
fn dom_tokens_render_init_with_old_state(
25+
Self(this): Self,
1926
dom_token_list: &mut impl crate::DomTokenList,
20-
state: &mut Self::UpdateWithState,
27+
old_state: &mut Self::State,
2128
) {
22-
T::update_with_state(this.0, dom_token_list, state);
29+
T::dom_tokens_render_init_with_old_state(this, dom_token_list, old_state)
2330
}
2431

25-
fn remove_with_state(
32+
fn dom_tokens_render_update(
33+
Self(this): Self,
2634
dom_token_list: &mut impl crate::DomTokenList,
27-
state: &mut Self::UpdateWithState,
35+
state: &mut Self::State,
2836
) {
29-
T::remove_with_state(dom_token_list, state);
37+
T::dom_tokens_render_update(this, dom_token_list, state)
3038
}
3139

3240
type DomTokensIntoAsyncStrIter = T::DomTokensIntoAsyncStrIter;

0 commit comments

Comments
 (0)