holochain_integrity_types/action/
builder.rs1use super::EntryType;
2use super::MigrationTarget;
3use super::Timestamp;
4use crate::action;
5use crate::link::LinkTag;
6use crate::link::LinkType;
7use crate::ActionUnweighed;
8use crate::ActionWeighed;
9use crate::EntryRateWeight;
10use crate::MembraneProof;
11use crate::RateWeight;
12use crate::ZomeIndex;
13use action::Dna;
14use holo_hash::ActionHash;
15use holo_hash::AgentPubKey;
16use holo_hash::AnyLinkableHash;
17use holo_hash::EntryHash;
18
19#[derive(Clone, Debug)]
20pub struct ActionBuilderCommon {
21 pub author: AgentPubKey,
22 pub timestamp: Timestamp,
23 pub action_seq: u32,
24 pub prev_action: ActionHash,
25}
26
27impl ActionBuilderCommon {
28 pub fn new(
29 author: AgentPubKey,
30 timestamp: Timestamp,
31 action_seq: u32,
32 prev_action: ActionHash,
33 ) -> Self {
34 Self {
35 author,
36 timestamp,
37 action_seq,
38 prev_action,
39 }
40 }
41}
42
43pub trait ActionBuilder<U: ActionUnweighed>: Sized {
58 fn build(self, common: ActionBuilderCommon) -> U;
59}
60
61macro_rules! builder_variant {
62 ( $name: ident <$weight : ty> { $($field: ident : $t: ty),* $(,)? } ) => {
63
64 #[derive(Clone, Debug, PartialEq, Eq)]
65 pub struct $name {
66 $(pub $field : $t,)*
67 }
68
69
70 #[allow(clippy::new_without_default)]
71 impl $name {
72 pub fn new($($field : $t),* ) -> Self {
73 Self {
74 $($field,)*
75 }
76 }
77 }
78
79 impl ActionBuilder<action::$name<()>> for $name {
80 fn build(self, common: ActionBuilderCommon) -> action::$name<()> {
81 let ActionBuilderCommon {
82 author,
83 timestamp,
84 action_seq,
85 prev_action,
86 } = common;
87
88 action::$name {
89 weight: (),
90 author,
91 timestamp,
92 action_seq,
93 prev_action,
94 $($field : self.$field,)*
95 }
96 }
97 }
98
99
100 impl ActionWeighed for action::$name {
101 type Unweighed = action::$name<()>;
102 type Weight = $weight;
103
104 fn into_action(self) -> action::Action {
105 action::Action::$name(self)
106 }
107
108 fn unweighed(self) -> action::$name<()> {
109 action::$name::<()> {
110 weight: (),
111 author: self.author,
112 timestamp: self.timestamp,
113 action_seq: self.action_seq,
114 prev_action: self.prev_action,
115 $($field: self.$field),*
116 }
117 }
118 }
119
120 impl ActionUnweighed for action::$name<()> {
121 type Weighed = action::$name;
122 type Weight = $weight;
123
124 fn weighed(self, weight: $weight) -> action::$name {
125 action::$name {
126 weight,
127 author: self.author,
128 timestamp: self.timestamp,
129 action_seq: self.action_seq,
130 prev_action: self.prev_action,
131 $($field: self.$field),*
132 }
133 }
134 }
135
136 #[cfg(feature = "test_utils")]
137 impl action::$name {
138 pub fn from_builder(common: ActionBuilderCommon, $($field : $t),*) -> Self {
139 let builder = $name {
140 $($field,)*
141 };
142
143 builder.build(common).weighed(Default::default())
144 }
145 }
146 };
147
148 ( $name: ident { $($field: ident : $t: ty),* $( $(,)? | $($dfield: ident : $dt: ty),* )? $(,)? } ) => {
149
150 #[derive(Clone, Debug, PartialEq, Eq)]
151 pub struct $name {
152 $(pub $field : $t,)*
153 $( $(pub $dfield : $dt),* )?
154 }
155
156 #[allow(clippy::new_without_default)]
157 impl $name {
158 pub fn new($($field : $t),* ) -> Self {
159 Self {
160 $($field,)*
161 $( $($dfield : Default::default()),* )?
162 }
163 }
164
165 pub fn new_full($($field : $t,)* $( $($dfield : $dt),* )? ) -> Self {
166 Self {
167 $($field,)*
168 $( $($dfield),* )?
169 }
170 }
171 }
172
173 impl ActionWeighed for action::$name {
174 type Unweighed = action::$name;
175 type Weight = ();
176
177 fn into_action(self) -> action::Action {
178 action::Action::$name(self)
179 }
180
181 fn unweighed(self) -> Self::Unweighed {
182 self
183 }
184
185 }
186
187 impl ActionUnweighed for action::$name {
188 type Weighed = action::$name;
189 type Weight = ();
190
191 fn weighed(self, _weight: ()) -> action::$name {
192 self
193 }
194 }
195
196 impl ActionBuilder<action::$name> for $name {
197 fn build(self, common: ActionBuilderCommon) -> action::$name {
198 let ActionBuilderCommon {
199 author,
200 timestamp,
201 action_seq,
202 prev_action,
203 } = common;
204
205 action::$name {
206 author,
207 timestamp,
208 action_seq,
209 prev_action,
210 $($field : self.$field,)*
211 $( $($dfield : self.$dfield),* )?
212 }
213 }
214 }
215
216 impl From<($name, ActionBuilderCommon)> for action::$name {
217 fn from((n, h): ($name, ActionBuilderCommon)) -> action::$name {
218 n.build(h)
219 }
220 }
221
222 #[cfg(feature = "test_utils")]
223 impl action::$name {
224 pub fn from_builder(common: ActionBuilderCommon, $($field : $t),*) -> Self {
225 let builder = $name {
226 $($field,)*
227 $( $($dfield : Default::default()),* )?
228 };
229
230 builder.build(common)
231 }
232 }
233 }
234}
235
236builder_variant!(InitZomesComplete {});
237
238builder_variant!(CreateLink<RateWeight> {
239 base_address: AnyLinkableHash,
240 target_address: AnyLinkableHash,
241 zome_index: ZomeIndex,
242 link_type: LinkType,
243 tag: LinkTag,
244});
245
246builder_variant!(DeleteLink {
247 link_add_address: ActionHash,
248 base_address: AnyLinkableHash,
249});
250
251builder_variant!(OpenChain {
252 prev_target: MigrationTarget,
253 close_hash: ActionHash,
254});
255
256builder_variant!(CloseChain {
257 new_target: Option<MigrationTarget>,
258});
259
260builder_variant!(Create<EntryRateWeight> {
261 entry_type: EntryType,
262 entry_hash: EntryHash,
263});
264
265builder_variant!(Update<EntryRateWeight> {
266 original_entry_address: EntryHash,
267 original_action_address: ActionHash,
268
269 entry_type: EntryType,
270 entry_hash: EntryHash,
271});
272
273builder_variant!(Delete<RateWeight> {
274 deletes_address: ActionHash,
275 deletes_entry_address: EntryHash,
276});
277
278builder_variant!(AgentValidationPkg {
279 membrane_proof: Option<MembraneProof>,
280});
281
282#[cfg(feature = "test_utils")]
285impl Dna {
286 pub fn from_builder(hash: holo_hash::DnaHash, builder: ActionBuilderCommon) -> Self {
287 Self {
288 author: builder.author,
289 timestamp: builder.timestamp,
290 hash,
291 }
292 }
293}
294
295impl ActionWeighed for Dna {
298 type Unweighed = Dna;
299 type Weight = ();
300
301 fn into_action(self) -> action::Action {
302 action::Action::Dna(self)
303 }
304
305 fn unweighed(self) -> Self::Unweighed {
306 self
307 }
308}
309
310impl ActionUnweighed for Dna {
311 type Weighed = Dna;
312 type Weight = ();
313
314 fn weighed(self, _weight: ()) -> Dna {
315 self
316 }
317}