Skip to content

Commit 2b6a34b

Browse files
authored
feat(attachment): create TargetSpecificAttachmentFactoryBase (#1140)
1 parent 8c716e2 commit 2b6a34b

File tree

3 files changed

+82
-6
lines changed

3 files changed

+82
-6
lines changed

src/ops/factory_bases.rs

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ pub struct TypedResourceSetupChangeItem<'a, F: TargetFactoryBase + ?Sized> {
374374
}
375375

376376
#[async_trait]
377-
pub trait TargetFactoryBase: TargetFactory + Send + Sync + 'static {
377+
pub trait TargetFactoryBase: Send + Sync + 'static {
378378
type Spec: DeserializeOwned + Send + Sync;
379379
type DeclarationSpec: DeserializeOwned + Send + Sync;
380380

@@ -635,3 +635,79 @@ fn from_json_combined_state<T: Debug + Clone + Serialize + DeserializeOwned>(
635635
legacy_state_key: existing_states.legacy_state_key,
636636
})
637637
}
638+
639+
pub struct TypedTargetAttachmentState<F: TargetSpecificAttachmentFactoryBase + ?Sized> {
640+
pub setup_key: F::SetupKey,
641+
pub setup_state: F::SetupState,
642+
}
643+
644+
/// A factory for target-specific attachments.
645+
pub trait TargetSpecificAttachmentFactoryBase: Send + Sync + 'static {
646+
type TargetSpec: DeserializeOwned + Send + Sync;
647+
type Spec: DeserializeOwned + Send + Sync;
648+
type SetupKey: Debug + Clone + Serialize + DeserializeOwned + Eq + Hash + Send + Sync;
649+
type SetupState: Debug + Clone + Serialize + DeserializeOwned + Send + Sync;
650+
type SetupChange: interface::AttachmentSetupChange + Send + Sync;
651+
652+
fn get_state(
653+
&self,
654+
target_name: &str,
655+
target_spec: &Self::TargetSpec,
656+
attachment_spec: Self::Spec,
657+
) -> Result<TypedTargetAttachmentState<Self>>;
658+
659+
fn diff_setup_states(
660+
&self,
661+
key: &serde_json::Value,
662+
new_state: Option<serde_json::Value>,
663+
existing_states: setup::CombinedState<serde_json::Value>,
664+
) -> Result<Option<Self::SetupChange>>;
665+
666+
/// Deserialize the setup key from a JSON value.
667+
/// You can override this method to provide a custom deserialization logic, e.g. to perform backward compatible deserialization.
668+
fn deserialize_setup_key(key: serde_json::Value) -> Result<Self::SetupKey> {
669+
Ok(utils::deser::from_json_value(key)?)
670+
}
671+
}
672+
673+
#[async_trait]
674+
impl<T: TargetSpecificAttachmentFactoryBase> TargetAttachmentFactory for T {
675+
fn normalize_setup_key(&self, key: &serde_json::Value) -> Result<serde_json::Value> {
676+
let key: T::SetupKey = Self::deserialize_setup_key(key.clone())?;
677+
Ok(serde_json::to_value(key)?)
678+
}
679+
680+
fn get_state(
681+
&self,
682+
target_name: &str,
683+
target_spec: &serde_json::Map<String, serde_json::Value>,
684+
attachment_spec: serde_json::Value,
685+
) -> Result<interface::TargetAttachmentState> {
686+
let state = TargetSpecificAttachmentFactoryBase::get_state(
687+
self,
688+
target_name,
689+
&utils::deser::from_json_value(serde_json::Value::Object(target_spec.clone()))?,
690+
utils::deser::from_json_value(attachment_spec)?,
691+
)?;
692+
Ok(interface::TargetAttachmentState {
693+
setup_key: serde_json::to_value(state.setup_key)?,
694+
setup_state: serde_json::to_value(state.setup_state)?,
695+
})
696+
}
697+
698+
fn diff_setup_states(
699+
&self,
700+
key: &serde_json::Value,
701+
new_state: Option<serde_json::Value>,
702+
existing_states: setup::CombinedState<serde_json::Value>,
703+
) -> Result<Option<Box<dyn AttachmentSetupChange + Send + Sync>>> {
704+
let setup_change = self.diff_setup_states(
705+
&utils::deser::from_json_value(key.clone())?,
706+
new_state
707+
.map(|v| utils::deser::from_json_value(v))
708+
.transpose()?,
709+
from_json_combined_state(existing_states)?,
710+
)?;
711+
Ok(setup_change.map(|s| Box::new(s) as Box<dyn AttachmentSetupChange + Send + Sync>))
712+
}
713+
}

src/ops/interface.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ pub struct TargetAttachmentState {
322322
}
323323

324324
#[async_trait]
325-
pub trait AttachmentSetupChangeAction {
325+
pub trait AttachmentSetupChange {
326326
fn describe_change(&self) -> String;
327327

328328
async fn apply_change(&self) -> Result<()>;
@@ -346,7 +346,7 @@ pub trait TargetAttachmentFactory: Send + Sync {
346346
key: &serde_json::Value,
347347
new_state: Option<serde_json::Value>,
348348
existing_states: setup::CombinedState<serde_json::Value>,
349-
) -> Result<Option<Box<dyn AttachmentSetupChangeAction + Send + Sync>>>;
349+
) -> Result<Option<Box<dyn AttachmentSetupChange + Send + Sync>>>;
350350
}
351351

352352
#[derive(Clone)]

src/setup/states.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::ops::interface::AttachmentSetupChangeAction;
1+
use crate::ops::interface::AttachmentSetupChange;
22
/// Concepts:
33
/// - Resource: some setup that needs to be tracked and maintained.
44
/// - Setup State: current state of a resource.
@@ -402,8 +402,8 @@ pub trait ObjectSetupChange {
402402

403403
#[derive(Default)]
404404
pub struct AttachmentsSetupChange {
405-
pub deletes: Vec<Box<dyn AttachmentSetupChangeAction + Send + Sync>>,
406-
pub upserts: Vec<Box<dyn AttachmentSetupChangeAction + Send + Sync>>,
405+
pub deletes: Vec<Box<dyn AttachmentSetupChange + Send + Sync>>,
406+
pub upserts: Vec<Box<dyn AttachmentSetupChange + Send + Sync>>,
407407
}
408408

409409
impl AttachmentsSetupChange {

0 commit comments

Comments
 (0)