@@ -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,101 @@ 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+ #[ async_trait]
646+ pub trait TargetSpecificAttachmentFactoryBase : Send + Sync + ' static {
647+ type TargetKey : Debug + Clone + Serialize + DeserializeOwned + Eq + Hash + Send + Sync ;
648+ type TargetSpec : DeserializeOwned + Send + Sync ;
649+ type Spec : DeserializeOwned + Send + Sync ;
650+ type SetupKey : Debug + Clone + Serialize + DeserializeOwned + Eq + Hash + Send + Sync ;
651+ type SetupState : Debug + Clone + Serialize + DeserializeOwned + Send + Sync ;
652+ type SetupChange : interface:: AttachmentSetupChange + Send + Sync ;
653+
654+ fn name ( & self ) -> & str ;
655+
656+ fn get_state (
657+ & self ,
658+ target_name : & str ,
659+ target_spec : & Self :: TargetSpec ,
660+ attachment_spec : Self :: Spec ,
661+ ) -> Result < TypedTargetAttachmentState < Self > > ;
662+
663+ async fn diff_setup_states (
664+ & self ,
665+ target_key : & Self :: TargetKey ,
666+ attachment_key : & Self :: SetupKey ,
667+ new_state : Option < Self :: SetupState > ,
668+ existing_states : setup:: CombinedState < Self :: SetupState > ,
669+ context : & interface:: FlowInstanceContext ,
670+ ) -> Result < Option < Self :: SetupChange > > ;
671+
672+ /// Deserialize the setup key from a JSON value.
673+ /// You can override this method to provide a custom deserialization logic, e.g. to perform backward compatible deserialization.
674+ fn deserialize_setup_key ( key : serde_json:: Value ) -> Result < Self :: SetupKey > {
675+ Ok ( utils:: deser:: from_json_value ( key) ?)
676+ }
677+
678+ fn register ( self , registry : & mut ExecutorFactoryRegistry ) -> Result < ( ) >
679+ where
680+ Self : Sized ,
681+ {
682+ registry. register (
683+ self . name ( ) . to_string ( ) ,
684+ ExecutorFactory :: TargetAttachment ( Arc :: new ( self ) ) ,
685+ )
686+ }
687+ }
688+
689+ #[ async_trait]
690+ impl < T : TargetSpecificAttachmentFactoryBase > TargetAttachmentFactory for T {
691+ fn normalize_setup_key ( & self , key : & serde_json:: Value ) -> Result < serde_json:: Value > {
692+ let key: T :: SetupKey = Self :: deserialize_setup_key ( key. clone ( ) ) ?;
693+ Ok ( serde_json:: to_value ( key) ?)
694+ }
695+
696+ fn get_state (
697+ & self ,
698+ target_name : & str ,
699+ target_spec : & serde_json:: Map < String , serde_json:: Value > ,
700+ attachment_spec : serde_json:: Value ,
701+ ) -> Result < interface:: TargetAttachmentState > {
702+ let state = TargetSpecificAttachmentFactoryBase :: get_state (
703+ self ,
704+ target_name,
705+ & utils:: deser:: from_json_value ( serde_json:: Value :: Object ( target_spec. clone ( ) ) ) ?,
706+ utils:: deser:: from_json_value ( attachment_spec) ?,
707+ ) ?;
708+ Ok ( interface:: TargetAttachmentState {
709+ setup_key : serde_json:: to_value ( state. setup_key ) ?,
710+ setup_state : serde_json:: to_value ( state. setup_state ) ?,
711+ } )
712+ }
713+
714+ async fn diff_setup_states (
715+ & self ,
716+ target_key : & serde_json:: Value ,
717+ attachment_key : & serde_json:: Value ,
718+ new_state : Option < serde_json:: Value > ,
719+ existing_states : setup:: CombinedState < serde_json:: Value > ,
720+ context : & interface:: FlowInstanceContext ,
721+ ) -> Result < Option < Box < dyn AttachmentSetupChange + Send + Sync > > > {
722+ let setup_change = self
723+ . diff_setup_states (
724+ & utils:: deser:: from_json_value ( target_key. clone ( ) ) ?,
725+ & utils:: deser:: from_json_value ( attachment_key. clone ( ) ) ?,
726+ new_state
727+ . map ( |v| utils:: deser:: from_json_value ( v) )
728+ . transpose ( ) ?,
729+ from_json_combined_state ( existing_states) ?,
730+ context,
731+ )
732+ . await ?;
733+ Ok ( setup_change. map ( |s| Box :: new ( s) as Box < dyn AttachmentSetupChange + Send + Sync > ) )
734+ }
735+ }
0 commit comments