tf_provider/resource.rs
1// This file is part of the tf-provider project
2//
3// Copyright (C) ANEO, 2024-2024. All rights reserved.
4//
5// Licensed under the Apache License, Version 2.0 (the "License")
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
17//! [`Resource`] module
18
19use crate::attribute_path::AttributePath;
20use crate::diagnostics::Diagnostics;
21use crate::raw::RawValue;
22use crate::schema::Schema;
23use crate::utils::OptionFactor;
24
25use async_trait::async_trait;
26use serde::{Deserialize, Serialize};
27
28/// Trait for implementing a resource with automatic serialization/deserialization
29///
30/// See also: [`DynamicResource`]
31#[async_trait]
32pub trait Resource: Send + Sync {
33 /// State of the resource
34 ///
35 /// The state will be automatically serialized/deserialized at the border of the request.
36 type State<'a>: Serialize + Deserialize<'a> + Send;
37
38 /// Private state of the resource
39 ///
40 /// The private state will be automatically serialized/deserialized at the border of the request.
41 type PrivateState<'a>: Serialize + Deserialize<'a> + Send;
42
43 /// State of the provider metadata
44 ///
45 /// The state will be automatically serialized/deserialized at the border of the request.
46 type ProviderMetaState<'a>: Serialize + Deserialize<'a> + Send;
47
48 /// Get the schema of the resource
49 ///
50 /// # Arguments
51 ///
52 /// * `diags` - Diagnostics to record warnings and errors that occured when getting back the schema
53 ///
54 /// # Remarks
55 ///
56 /// The return is ignored if there is an error in diagnostics.
57 /// If the return is [`None`], an ad-hoc error is added to diagnostics.
58 fn schema(&self, diags: &mut Diagnostics) -> Option<Schema>;
59
60 /// Validate the configuration of the resource
61 ///
62 /// # Arguments
63 ///
64 /// * `diags` - Diagnostics to record warnings and errors that occured during validation
65 /// * `config` - State as declared in the Terraform file
66 ///
67 /// # Remarks
68 ///
69 /// The return is ignored if there is an error in diagnostics.
70 /// If the return is [`None`], an ad-hoc error is added to diagnostics.
71 async fn validate<'a>(&self, diags: &mut Diagnostics, config: Self::State<'a>) -> Option<()> {
72 _ = diags;
73 _ = config;
74 Some(())
75 }
76
77 /// Read the new state of the resource
78 ///
79 /// # Arguments
80 ///
81 /// * `diags` - Diagnostics to record warnings and errors that occured during the read
82 /// * `state` - State as stored in the Terraform state
83 /// * `private_state` - Private state as stored in the Terraform state
84 /// * `provider_meta_state` - State of the provider metadata as declared in the Terraform file
85 ///
86 /// # Remarks
87 ///
88 /// Return must be [`None`] if the resource has been destroyed externally.
89 /// Return must be [`Some`] if the resource is still there, even if there was errors while reading the resource.
90 async fn read<'a>(
91 &self,
92 diags: &mut Diagnostics,
93 state: Self::State<'a>,
94 private_state: Self::PrivateState<'a>,
95 provider_meta_state: Self::ProviderMetaState<'a>,
96 ) -> Option<(Self::State<'a>, Self::PrivateState<'a>)>;
97
98 /// Plan the creation of a new resource
99 ///
100 /// # Arguments
101 ///
102 /// * `diags` - Diagnostics to record warnings and errors that occured during the plan
103 /// * `proposed_state` - State proposed by Terraform
104 /// * `config_state` - State as declared in the Terraform file
105 /// * `provider_meta_state` - State of the provider metadata as declared in the Terraform file
106 ///
107 /// # Remarks
108 ///
109 /// The return is ignored if there is an error in diagnostics.
110 /// If the return is [`None`], an ad-hoc error is added to diagnostics.
111 async fn plan_create<'a>(
112 &self,
113 diags: &mut Diagnostics,
114 proposed_state: Self::State<'a>,
115 config_state: Self::State<'a>,
116 provider_meta_state: Self::ProviderMetaState<'a>,
117 ) -> Option<(Self::State<'a>, Self::PrivateState<'a>)>;
118
119 /// Plan the changes on the resource
120 ///
121 /// # Arguments
122 ///
123 /// * `diags` - Diagnostics to record warnings and errors that occured during the plan
124 /// * `prior_state` - State as stored in the Terraform state
125 /// * `proposed_state` - State proposed by Terraform
126 /// * `config_state` - State as declared in the Terraform file
127 /// * `private_state` - Private state as stored in the Terraform state
128 /// * `provider_meta_state` - State of the provider metadata as declared in the Terraform file
129 ///
130 /// # Remarks
131 ///
132 /// The return is ignored if there is an error in diagnostics.
133 /// If the return is [`None`], an ad-hoc error is added to diagnostics.
134 async fn plan_update<'a>(
135 &self,
136 diags: &mut Diagnostics,
137 prior_state: Self::State<'a>,
138 proposed_state: Self::State<'a>,
139 config_state: Self::State<'a>,
140 prior_private_state: Self::PrivateState<'a>,
141 provider_meta_state: Self::ProviderMetaState<'a>,
142 ) -> Option<(Self::State<'a>, Self::PrivateState<'a>, Vec<AttributePath>)>;
143
144 /// Plan the destruction of the resource
145 ///
146 /// # Arguments
147 ///
148 /// * `diags` - Diagnostics to record warnings and errors that occured during the plan
149 /// * `prior_state` - State as stored in the Terraform state
150 /// * `prior_private_state` - Private state as stored in the Terraform state
151 /// * `provider_meta_state` - State of the provider metadata as declared in the Terraform file
152 ///
153 /// # Remarks
154 ///
155 /// The return is ignored if there is an error in diagnostics.
156 /// If the return is [`None`], an ad-hoc error is added to diagnostics.
157 async fn plan_destroy<'a>(
158 &self,
159 diags: &mut Diagnostics,
160 prior_state: Self::State<'a>,
161 prior_private_state: Self::PrivateState<'a>,
162 provider_meta_state: Self::ProviderMetaState<'a>,
163 ) -> Option<Self::PrivateState<'a>>;
164
165 /// Create a new resource
166 ///
167 /// # Arguments
168 ///
169 /// * `diags` - Diagnostics to record warnings and errors that occured during the creation
170 /// * `planned_state` - State proposed by the provider upon plan
171 /// * `config_state` - State as declared in the Terraform file
172 /// * `planned_private_state` - Private state proposed by the provider upon plan
173 /// * `provider_meta_state` - State of the provider metadata as declared in the Terraform file
174 ///
175 /// # Remarks
176 ///
177 /// If the return is [`None`], an ad-hoc error is added to diagnostics.
178 /// Return must be [`Some`] if the resource was created, even if there was errors while creating the resource.
179 async fn create<'a>(
180 &self,
181 diags: &mut Diagnostics,
182 planned_state: Self::State<'a>,
183 config_state: Self::State<'a>,
184 planned_private_state: Self::PrivateState<'a>,
185 provider_meta_state: Self::ProviderMetaState<'a>,
186 ) -> Option<(Self::State<'a>, Self::PrivateState<'a>)>;
187
188 /// Apply the changes on the resource
189 ///
190 /// # Arguments
191 ///
192 /// * `diags` - Diagnostics to record warnings and errors that occured during the update
193 /// * `prior_state` - State as stored in the Terraform state
194 /// * `planned_state` - State proposed by the provider upon plan
195 /// * `config_state` - State as declared in the Terraform file
196 /// * `planned_private_state` - Private state proposed by the provider upon plan
197 /// * `provider_meta_state` - State of the provider metadata as declared in the Terraform file
198 ///
199 /// # Remarks
200 ///
201 /// If the return is [`None`], an ad-hoc error is added to diagnostics, and the resource state is kept unchanged.
202 /// Return must be [`Some`] if the resource was updated, even if there was errors while updated the resource.
203 async fn update<'a>(
204 &self,
205 diags: &mut Diagnostics,
206 prior_state: Self::State<'a>,
207 planned_state: Self::State<'a>,
208 config_state: Self::State<'a>,
209 planned_private_state: Self::PrivateState<'a>,
210 provider_meta_state: Self::ProviderMetaState<'a>,
211 ) -> Option<(Self::State<'a>, Self::PrivateState<'a>)>;
212
213 /// Destroy the resource
214 ///
215 /// # Arguments
216 ///
217 /// * `diags` - Diagnostics to record warnings and errors that occured during the destruction
218 /// * `prior_state` - State as stored in the Terraform state
219 /// * `planned_private_state` - Private state proposed by the provider upon plan
220 /// * `provider_meta_state` - State of the provider metadata as declared in the Terraform file
221 ///
222 /// # Remarks
223 ///
224 /// The return is ignored if there is an error in diagnostics.
225 /// If the return is [`None`], an ad-hoc error is added to diagnostics.
226 async fn destroy<'a>(
227 &self,
228 diags: &mut Diagnostics,
229 prior_state: Self::State<'a>,
230 planned_private_state: Self::PrivateState<'a>,
231 provider_meta_state: Self::ProviderMetaState<'a>,
232 ) -> Option<()>;
233
234 /// Import an existing resource
235 ///
236 /// # Arguments
237 ///
238 /// * `diags` - Diagnostics to record warnings and errors that occured during the import
239 /// * `id` - Opaque string that the provider can use to identify the actual resource to import
240 ///
241 /// # Remarks
242 ///
243 /// If the return is [`None`], an ad-hoc error is added to diagnostics.
244 /// Return must be [`Some`] if the resource was imported, even if there was errors while importing the resource.
245 async fn import<'a>(
246 &self,
247 diags: &mut Diagnostics,
248 id: String,
249 ) -> Option<(Self::State<'a>, Self::PrivateState<'a>)> {
250 _ = id;
251 diags.root_error_short("Import is not supported");
252 None
253 }
254
255 /// Upgrade the resource from a prior version of the resource
256 ///
257 /// # Arguments
258 ///
259 /// * `diags` - Diagnostics to record warnings and errors that occured during the import
260 /// * `version` - Prior version of the resource to upgrade as recorded in Terraform state
261 /// * `prior_state` - Prior state of the resource to upgrade as recorded in Terraform state
262 ///
263 /// # Remarks
264 ///
265 /// If the return is [`None`], an ad-hoc error is added to diagnostics, and the resource state is kept unchanged.
266 /// Return must be [`Some`] if the resource was upgraded, even if there was errors while upgraded the resource.
267 ///
268 /// Because the schema of the resource might have changed,
269 /// the prior state must be deserialized explicitely.
270 async fn upgrade<'a>(
271 &self,
272 diags: &mut Diagnostics,
273 version: i64,
274 prior_state: RawValue,
275 ) -> Option<Self::State<'a>> {
276 _ = version;
277 _ = prior_state;
278 diags.root_error_short("Upgrade is not supported");
279 None
280 }
281}
282
283/// Trait for implementing a resource *without* automatic serialization/deserialization
284///
285/// See also: [`Resource`]
286#[async_trait]
287pub trait DynamicResource: Send + Sync {
288 /// Get the schema of the resource
289 ///
290 /// # Arguments
291 ///
292 /// * `diags` - Diagnostics to record warnings and errors that occured when getting back the schema
293 ///
294 /// # Remarks
295 ///
296 /// The return is ignored if there is an error in diagnostics.
297 /// If the return is [`None`], an ad-hoc error is added to diagnostics.
298 fn schema(&self, diags: &mut Diagnostics) -> Option<Schema>;
299
300 /// Validate the configuration of the resource
301 ///
302 /// # Arguments
303 ///
304 /// * `diags` - Diagnostics to record warnings and errors that occured during validation
305 /// * `config` - State as declared in the Terraform file
306 ///
307 /// # Remarks
308 ///
309 /// The return is ignored if there is an error in diagnostics.
310 /// If the return is [`None`], an ad-hoc error is added to diagnostics.
311 async fn validate(&self, diags: &mut Diagnostics, config: RawValue) -> Option<()> {
312 _ = diags;
313 _ = config;
314 Some(())
315 }
316
317 /// Read the new state of the resource
318 ///
319 /// # Arguments
320 ///
321 /// * `diags` - Diagnostics to record warnings and errors that occured during the read
322 /// * `state` - State as stored in the Terraform state
323 /// * `private_state` - Private state as stored in the Terraform state
324 /// * `provider_meta_state` - State of the provider metadata as declared in the Terraform file
325 ///
326 /// # Remarks
327 ///
328 /// Return must be [`None`] if the resource has been destroyed externally.
329 /// Return must be [`Some`] if the resource is still there, even if there was errors while reading the resource.
330 async fn read(
331 &self,
332 diags: &mut Diagnostics,
333 state: RawValue,
334 private_state: Vec<u8>,
335 provider_meta_state: RawValue,
336 ) -> Option<(RawValue, Vec<u8>)>;
337
338 /// Plan the creation of a new resource
339 ///
340 /// # Arguments
341 ///
342 /// * `diags` - Diagnostics to record warnings and errors that occured during the plan
343 /// * `proposed_state` - State proposed by Terraform
344 /// * `config_state` - State as declared in the Terraform file
345 /// * `provider_meta_state` - State of the provider metadata as declared in the Terraform file
346 ///
347 /// # Remarks
348 ///
349 /// The return is ignored if there is an error in diagnostics.
350 /// If the return is [`None`], an ad-hoc error is added to diagnostics.
351 async fn plan_create(
352 &self,
353 diags: &mut Diagnostics,
354 proposed_state: RawValue,
355 config_state: RawValue,
356 provider_meta_state: RawValue,
357 ) -> Option<(RawValue, Vec<u8>)>;
358
359 /// Plan the changes on the resource
360 ///
361 /// # Arguments
362 ///
363 /// * `diags` - Diagnostics to record warnings and errors that occured during the plan
364 /// * `prior_state` - State as stored in the Terraform state
365 /// * `proposed_state` - State proposed by Terraform
366 /// * `config_state` - State as declared in the Terraform file
367 /// * `private_state` - Private state as stored in the Terraform state
368 /// * `provider_meta_state` - State of the provider metadata as declared in the Terraform file
369 ///
370 /// # Remarks
371 ///
372 /// The return is ignored if there is an error in diagnostics.
373 /// If the return is [`None`], an ad-hoc error is added to diagnostics.
374 async fn plan_update(
375 &self,
376 diags: &mut Diagnostics,
377 prior_state: RawValue,
378 proposed_state: RawValue,
379 config_state: RawValue,
380 prior_private_state: Vec<u8>,
381 provider_meta_state: RawValue,
382 ) -> Option<(RawValue, Vec<u8>, Vec<AttributePath>)>;
383
384 /// Plan the destruction of the resource
385 ///
386 /// # Arguments
387 ///
388 /// * `diags` - Diagnostics to record warnings and errors that occured during the plan
389 /// * `prior_state` - State as stored in the Terraform state
390 /// * `prior_private_state` - Private state as stored in the Terraform state
391 /// * `provider_meta_state` - State of the provider metadata as declared in the Terraform file
392 ///
393 /// # Remarks
394 ///
395 /// The return is ignored if there is an error in diagnostics.
396 /// If the return is [`None`], an ad-hoc error is added to diagnostics.
397 async fn plan_destroy(
398 &self,
399 diags: &mut Diagnostics,
400 prior_state: RawValue,
401 prior_private_state: Vec<u8>,
402 provider_meta_state: RawValue,
403 ) -> Option<Vec<u8>>;
404
405 /// Create a new resource
406 ///
407 /// # Arguments
408 ///
409 /// * `diags` - Diagnostics to record warnings and errors that occured during the creation
410 /// * `planned_state` - State proposed by the provider upon plan
411 /// * `config_state` - State as declared in the Terraform file
412 /// * `planned_private_state` - Private state proposed by the provider upon plan
413 /// * `provider_meta_state` - State of the provider metadata as declared in the Terraform file
414 ///
415 /// # Remarks
416 ///
417 /// If the return is [`None`], an ad-hoc error is added to diagnostics.
418 /// Return must be [`Some`] if the resource was created, even if there was errors while creating the resource.
419 async fn create(
420 &self,
421 diags: &mut Diagnostics,
422 planned_state: RawValue,
423 config_state: RawValue,
424 planned_private_state: Vec<u8>,
425 provider_meta_state: RawValue,
426 ) -> Option<(RawValue, Vec<u8>)>;
427
428 /// Apply the changes on the resource
429 ///
430 /// # Arguments
431 ///
432 /// * `diags` - Diagnostics to record warnings and errors that occured during the update
433 /// * `prior_state` - State as stored in the Terraform state
434 /// * `planned_state` - State proposed by the provider upon plan
435 /// * `config_state` - State as declared in the Terraform file
436 /// * `planned_private_state` - Private state proposed by the provider upon plan
437 /// * `provider_meta_state` - State of the provider metadata as declared in the Terraform file
438 ///
439 /// # Remarks
440 ///
441 /// If the return is [`None`], an ad-hoc error is added to diagnostics, and the resource state is kept unchanged.
442 /// Return must be [`Some`] if the resource was updated, even if there was errors while updated the resource.
443 async fn update(
444 &self,
445 diags: &mut Diagnostics,
446 prior_state: RawValue,
447 planned_state: RawValue,
448 config_state: RawValue,
449 planned_private_state: Vec<u8>,
450 provider_meta_state: RawValue,
451 ) -> Option<(RawValue, Vec<u8>)>;
452
453 /// Destroy the resource
454 ///
455 /// # Arguments
456 ///
457 /// * `diags` - Diagnostics to record warnings and errors that occured during the destruction
458 /// * `prior_state` - State as stored in the Terraform state
459 /// * `planned_private_state` - Private state proposed by the provider upon plan
460 /// * `provider_meta_state` - State of the provider metadata as declared in the Terraform file
461 ///
462 /// # Remarks
463 ///
464 /// The return is ignored if there is an error in diagnostics.
465 /// If the return is [`None`], an ad-hoc error is added to diagnostics.
466 async fn destroy(
467 &self,
468 diags: &mut Diagnostics,
469 prior_state: RawValue,
470 planned_private_state: Vec<u8>,
471 provider_meta_state: RawValue,
472 ) -> Option<()>;
473
474 /// Import an existing resource
475 ///
476 /// # Arguments
477 ///
478 /// * `diags` - Diagnostics to record warnings and errors that occured during the import
479 /// * `id` - Opaque string that the provider can use to identify the actual resource to import
480 ///
481 /// # Remarks
482 ///
483 /// If the return is [`None`], an ad-hoc error is added to diagnostics.
484 /// Return must be [`Some`] if the resource was imported, even if there was errors while importing the resource.
485 async fn import(&self, diags: &mut Diagnostics, id: String) -> Option<(RawValue, Vec<u8>)> {
486 _ = id;
487 diags.root_error_short("Import is not supported");
488 None
489 }
490
491 /// Upgrade the resource
492 ///
493 /// # Arguments
494 ///
495 /// * `diags` - Diagnostics to record warnings and errors that occured during the import
496 /// * `version` - Prior version of the resource to upgrade as recorded in Terraform state
497 /// * `prior_state` - Prior state of the resource to upgrade as recorded in Terraform state
498 ///
499 /// # Remarks
500 ///
501 /// If the return is [`None`], an ad-hoc error is added to diagnostics, and the resource state is kept unchanged.
502 /// Return must be [`Some`] if the resource was upgraded, even if there was errors while upgraded the resource.
503 async fn upgrade(
504 &self,
505 diags: &mut Diagnostics,
506 version: i64,
507 prior_state: RawValue,
508 ) -> Option<RawValue> {
509 _ = version;
510 _ = prior_state;
511 diags.root_error_short("Upgrade is not supported");
512 None
513 }
514}
515
516#[async_trait]
517impl<T: Resource> DynamicResource for T {
518 /// Get the schema of the resource
519 fn schema(&self, diags: &mut Diagnostics) -> Option<Schema> {
520 <T as Resource>::schema(self, diags)
521 }
522 /// Validate the configuration of the resource
523 async fn validate(&self, diags: &mut Diagnostics, config: RawValue) -> Option<()> {
524 let config = config.deserialize(diags)?;
525 <T as Resource>::validate(self, diags, config).await
526 }
527 /// Read the new state of the resource
528 async fn read(
529 &self,
530 diags: &mut Diagnostics,
531 state: RawValue,
532 private_state: Vec<u8>,
533 provider_meta_state: RawValue,
534 ) -> Option<(RawValue, Vec<u8>)> {
535 let private_state = RawValue::MessagePack(private_state);
536 let (state, private_state, provider_meta_state) = (
537 state.deserialize(diags),
538 private_state.deserialize(diags),
539 provider_meta_state.deserialize(diags),
540 )
541 .factor()?;
542
543 let (state, private_state) =
544 <T as Resource>::read(self, diags, state, private_state, provider_meta_state).await?;
545
546 (
547 RawValue::serialize(diags, &state),
548 RawValue::serialize_vec(diags, &private_state),
549 )
550 .factor()
551 }
552 /// Plan the creation of a new resource
553 async fn plan_create(
554 &self,
555 diags: &mut Diagnostics,
556 proposed_state: RawValue,
557 config_state: RawValue,
558 provider_meta_state: RawValue,
559 ) -> Option<(RawValue, Vec<u8>)> {
560 let (proposed_state, config_state, provider_meta_state) = (
561 proposed_state.deserialize(diags),
562 config_state.deserialize(diags),
563 provider_meta_state.deserialize(diags),
564 )
565 .factor()?;
566
567 let (state, private_state) = <T as Resource>::plan_create(
568 self,
569 diags,
570 proposed_state,
571 config_state,
572 provider_meta_state,
573 )
574 .await?;
575
576 (
577 RawValue::serialize(diags, &state),
578 RawValue::serialize_vec(diags, &private_state),
579 )
580 .factor()
581 }
582 /// Plan the changes on the resource
583 async fn plan_update(
584 &self,
585 diags: &mut Diagnostics,
586 prior_state: RawValue,
587 proposed_state: RawValue,
588 config_state: RawValue,
589 prior_private_state: Vec<u8>,
590 provider_meta_state: RawValue,
591 ) -> Option<(RawValue, Vec<u8>, Vec<AttributePath>)> {
592 let prior_private_state = RawValue::MessagePack(prior_private_state);
593 let (prior_state, proposed_state, config_state, prior_private_state, provider_meta_state) =
594 (
595 prior_state.deserialize(diags),
596 proposed_state.deserialize(diags),
597 config_state.deserialize(diags),
598 prior_private_state.deserialize(diags),
599 provider_meta_state.deserialize(diags),
600 )
601 .factor()?;
602
603 let (state, private_state, destroy_triggers) = <T as Resource>::plan_update(
604 self,
605 diags,
606 prior_state,
607 proposed_state,
608 config_state,
609 prior_private_state,
610 provider_meta_state,
611 )
612 .await?;
613
614 (
615 RawValue::serialize(diags, &state),
616 RawValue::serialize_vec(diags, &private_state),
617 Some(destroy_triggers),
618 )
619 .factor()
620 }
621 /// Plan the destruction of the resource
622 async fn plan_destroy(
623 &self,
624 diags: &mut Diagnostics,
625 prior_state: RawValue,
626 prior_private_state: Vec<u8>,
627 provider_meta_state: RawValue,
628 ) -> Option<Vec<u8>> {
629 let prior_private_state = RawValue::MessagePack(prior_private_state);
630 let (prior_state, prior_private_state, provider_meta_state) = (
631 prior_state.deserialize(diags),
632 prior_private_state.deserialize(diags),
633 provider_meta_state.deserialize(diags),
634 )
635 .factor()?;
636
637 let private_state = <T as Resource>::plan_destroy(
638 self,
639 diags,
640 prior_state,
641 prior_private_state,
642 provider_meta_state,
643 )
644 .await?;
645
646 RawValue::serialize_vec(diags, &private_state)
647 }
648 /// Create a new resource
649 async fn create(
650 &self,
651 diags: &mut Diagnostics,
652 planned_state: RawValue,
653 config_state: RawValue,
654 planned_private_state: Vec<u8>,
655 provider_meta_state: RawValue,
656 ) -> Option<(RawValue, Vec<u8>)> {
657 let planned_private_state = RawValue::MessagePack(planned_private_state);
658 let (planned_state, config_state, planned_private_state, provider_meta_state) = (
659 planned_state.deserialize(diags),
660 config_state.deserialize(diags),
661 planned_private_state.deserialize(diags),
662 provider_meta_state.deserialize(diags),
663 )
664 .factor()?;
665 let (state, private_state) = <T as Resource>::create(
666 self,
667 diags,
668 planned_state,
669 config_state,
670 planned_private_state,
671 provider_meta_state,
672 )
673 .await?;
674 (
675 RawValue::serialize(diags, &state),
676 RawValue::serialize_vec(diags, &private_state),
677 )
678 .factor()
679 }
680 /// Apply the changes on the resource
681 async fn update(
682 &self,
683 diags: &mut Diagnostics,
684 prior_state: RawValue,
685 planned_state: RawValue,
686 config_state: RawValue,
687 planned_private_state: Vec<u8>,
688 provider_meta_state: RawValue,
689 ) -> Option<(RawValue, Vec<u8>)> {
690 let planned_private_state = RawValue::MessagePack(planned_private_state);
691 let (prior_state, planned_state, config_state, planned_private_state, provider_meta_state) =
692 (
693 prior_state.deserialize(diags),
694 planned_state.deserialize(diags),
695 config_state.deserialize(diags),
696 planned_private_state.deserialize(diags),
697 provider_meta_state.deserialize(diags),
698 )
699 .factor()?;
700 let (state, private_state) = <T as Resource>::update(
701 self,
702 diags,
703 prior_state,
704 planned_state,
705 config_state,
706 planned_private_state,
707 provider_meta_state,
708 )
709 .await?;
710 (
711 RawValue::serialize(diags, &state),
712 RawValue::serialize_vec(diags, &private_state),
713 )
714 .factor()
715 }
716 /// Destroy the resource
717 async fn destroy(
718 &self,
719 diags: &mut Diagnostics,
720 prior_state: RawValue,
721 planned_private_state: Vec<u8>,
722 provider_meta_state: RawValue,
723 ) -> Option<()> {
724 let planned_private_state = RawValue::MessagePack(planned_private_state);
725 let (prior_state, planned_private_state, provider_meta_state) = (
726 prior_state.deserialize(diags),
727 planned_private_state.deserialize(diags),
728 provider_meta_state.deserialize(diags),
729 )
730 .factor()?;
731
732 <T as Resource>::destroy(
733 self,
734 diags,
735 prior_state,
736 planned_private_state,
737 provider_meta_state,
738 )
739 .await
740 }
741 /// Import an existing resource
742 async fn import(&self, diags: &mut Diagnostics, id: String) -> Option<(RawValue, Vec<u8>)> {
743 let (state, private_state) = <T as Resource>::import(self, diags, id).await?;
744 (
745 RawValue::serialize(diags, &state),
746 RawValue::serialize_vec(diags, &private_state),
747 )
748 .factor()
749 }
750 /// Upgrade the resource
751 async fn upgrade(
752 &self,
753 diags: &mut Diagnostics,
754 version: i64,
755 prior_state: RawValue,
756 ) -> Option<RawValue> {
757 let state = <T as Resource>::upgrade(self, diags, version, prior_state).await?;
758 RawValue::serialize(diags, &state)
759 }
760}
761
762impl<T: Resource + 'static> From<T> for Box<dyn DynamicResource> {
763 fn from(value: T) -> Self {
764 Box::new(value)
765 }
766}