radix_engine/system/
system_substates.rs

1use crate::internal_prelude::*;
2
3#[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)]
4pub struct FieldSubstateV1<V> {
5    pub payload: V,
6    pub lock_status: LockStatus,
7}
8
9// Note - we manually version these instead of using the defined_versioned! macro,
10// to avoid FieldSubstate<X> implementing UpgradableVersioned and inheriting
11// potentially confusing methods
12#[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)]
13pub enum FieldSubstate<T> {
14    V1(FieldSubstateV1<T>),
15}
16
17impl<V> FieldSubstate<V> {
18    pub fn new_field(payload: V, lock_status: LockStatus) -> Self {
19        FieldSubstate::V1(FieldSubstateV1 {
20            payload,
21            lock_status,
22        })
23    }
24
25    pub fn new_unlocked_field(payload: V) -> Self {
26        Self::new_field(payload, LockStatus::Unlocked)
27    }
28
29    pub fn new_locked_field(payload: V) -> Self {
30        Self::new_field(payload, LockStatus::Locked)
31    }
32
33    pub fn lock(&mut self) {
34        let lock_status = match self {
35            FieldSubstate::V1(FieldSubstateV1 { lock_status, .. }) => lock_status,
36        };
37        *lock_status = LockStatus::Locked;
38    }
39
40    pub fn payload(&self) -> &V {
41        match self {
42            FieldSubstate::V1(FieldSubstateV1 { payload, .. }) => payload,
43        }
44    }
45
46    pub fn lock_status(&self) -> LockStatus {
47        match self {
48            FieldSubstate::V1(FieldSubstateV1 { lock_status, .. }) => *lock_status,
49        }
50    }
51
52    pub fn into_payload(self) -> V {
53        match self {
54            FieldSubstate::V1(FieldSubstateV1 { payload, .. }) => payload,
55        }
56    }
57
58    pub fn into_lock_status(self) -> LockStatus {
59        match self {
60            FieldSubstate::V1(FieldSubstateV1 { lock_status, .. }) => lock_status,
61        }
62    }
63}
64
65#[derive(Debug, Copy, Clone, PartialEq, Eq, ScryptoSbor)]
66pub enum LockStatus {
67    Unlocked,
68    Locked,
69}
70
71#[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)]
72pub struct KeyValueEntrySubstateV1<V> {
73    pub value: Option<V>,
74    pub lock_status: LockStatus,
75}
76
77// Note - we manually version these instead of using the defined_versioned! macro,
78// to avoid KeyValueEntrySubstate<X> implementing UpgradableVersioned and inheriting
79// potentially confusing methods
80#[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)]
81pub enum KeyValueEntrySubstate<V> {
82    V1(KeyValueEntrySubstateV1<V>),
83}
84
85impl<V> KeyValueEntrySubstate<V> {
86    pub fn lock(&mut self) {
87        match self {
88            KeyValueEntrySubstate::V1(substate) => {
89                substate.lock_status = LockStatus::Locked;
90            }
91        }
92    }
93
94    pub fn into_value(self) -> Option<V> {
95        match self {
96            KeyValueEntrySubstate::V1(KeyValueEntrySubstateV1 { value, .. }) => value,
97        }
98    }
99
100    pub fn is_locked(&self) -> bool {
101        match self {
102            KeyValueEntrySubstate::V1(substate) => {
103                matches!(substate.lock_status, LockStatus::Locked)
104            }
105        }
106    }
107
108    pub fn unlocked_entry(value: V) -> Self {
109        Self::V1(KeyValueEntrySubstateV1 {
110            value: Some(value),
111            lock_status: LockStatus::Unlocked,
112        })
113    }
114
115    pub fn locked_entry(value: V) -> Self {
116        Self::V1(KeyValueEntrySubstateV1 {
117            value: Some(value),
118            lock_status: LockStatus::Locked,
119        })
120    }
121
122    pub fn locked_empty_entry() -> Self {
123        Self::V1(KeyValueEntrySubstateV1 {
124            value: None,
125            lock_status: LockStatus::Locked,
126        })
127    }
128
129    pub fn remove(&mut self) -> Option<V> {
130        match self {
131            KeyValueEntrySubstate::V1(substate) => substate.value.take(),
132        }
133    }
134
135    pub fn lock_status(&self) -> LockStatus {
136        match self {
137            KeyValueEntrySubstate::V1(substate) => substate.lock_status.clone(),
138        }
139    }
140}
141
142impl<V> Default for KeyValueEntrySubstate<V> {
143    fn default() -> Self {
144        Self::V1(KeyValueEntrySubstateV1 {
145            value: None,
146            lock_status: LockStatus::Unlocked,
147        })
148    }
149}
150
151pub type IndexEntrySubstateV1<V> = V;
152
153// Note - we manually version these instead of using the defined_versioned! macro,
154// to avoid IndexEntrySubstate<X> implementing UpgradableVersioned and inheriting
155// potentially confusing methods
156#[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)]
157pub enum IndexEntrySubstate<V> {
158    V1(IndexEntrySubstateV1<V>),
159}
160
161impl<V> IndexEntrySubstate<V> {
162    pub fn entry(value: V) -> Self {
163        Self::V1(value)
164    }
165
166    pub fn value(&self) -> &V {
167        match self {
168            IndexEntrySubstate::V1(value) => value,
169        }
170    }
171
172    pub fn into_value(self) -> V {
173        match self {
174            IndexEntrySubstate::V1(value) => value,
175        }
176    }
177}
178
179pub type SortedIndexEntrySubstateV1<V> = V;
180
181// Note - we manually version these instead of using the defined_versioned! macro,
182// to avoid SortedIndexEntrySubstate<X> implementing UpgradableVersioned and inheriting
183// potentially confusing methods
184#[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)]
185pub enum SortedIndexEntrySubstate<V> {
186    V1(SortedIndexEntrySubstateV1<V>),
187}
188
189impl<V> SortedIndexEntrySubstate<V> {
190    pub fn entry(value: V) -> Self {
191        Self::V1(value)
192    }
193
194    pub fn value(&self) -> &V {
195        match self {
196            SortedIndexEntrySubstate::V1(value) => value,
197        }
198    }
199
200    pub fn into_value(self) -> V {
201        match self {
202            SortedIndexEntrySubstate::V1(value) => value,
203        }
204    }
205}