1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
// The policies that decide which subcomposed slots a subcompose state keeps
// for reuse and which slot's nodes another slot may take.
use SlotId;
use crateHashSet;
/// Policy that decides which previously composed slots should be retained for
/// potential reuse during the next subcompose pass.
///
/// Note: This trait does NOT require Send + Sync because the compose runtime
/// is single-threaded (uses Rc/RefCell throughout).
/// A slot with the content type registered for it, if any: what a
/// [`SlotReusePolicy`] decides reuse by.
/// Default reuse policy that mirrors Jetpack Compose behaviour: dispose
/// everything from the tail so that the next measurement can decide which
/// content to keep alive. Compatibility defaults to exact slot matches.
;
/// Reuse policy that allows cross-slot reuse when content types match.
///
/// This policy enables efficient recycling of layout nodes across different
/// slot IDs when they share the same content type (e.g., list items with
/// similar structure but different data). Two slots without a content type
/// are compatible too.
///
/// # Example
///
/// ```
/// use cranpose_core::{ContentTypeReusePolicy, SlotId, SlotReusePolicy, TypedSlot};
///
/// let policy = ContentTypeReusePolicy;
/// let item = |id, content_type| TypedSlot {
/// id: SlotId::new(id),
/// content_type,
/// };
///
/// // Slot 1 can reuse slot 2's node since they share content type 2
/// assert!(policy.are_compatible(item(2, Some(2)), item(1, Some(2))));
/// // A header cannot take an item's node
/// assert!(!policy.are_compatible(item(2, Some(2)), item(0, Some(1))));
/// ```
;