Skip to main content

harmos_operations/lifecycle/
initialize.rs

1/* ***
2 *
3 * Harmos
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * ***
8 */
9
10/* === Modules === */
11
12/* === Re-Exports === */
13
14/* === Imports === */
15
16use harmos_domain::{MemorySize, schema::Described};
17
18/* === Constants === */
19
20/* === Macros === */
21
22/* === Type Aliases === */
23
24/* === Structs === */
25
26#[harmos::operation(harmos_path = crate, codec = manual, id = "harmos.initialize", response = (), policy = super::POLICY, )]
27#[derive(Clone, PartialEq, Debug, Default)]
28pub struct Initialize {
29    pub config_json: Vec<u8>,
30    pub generation_context: Vec<u8>,
31    pub assignments: Vec<u8>,
32}
33
34#[cfg(feature = "lifecycle")]
35pub struct Control {
36    #[cfg(feature = "lifecycle")]
37    instance: Box<dyn harmos_sdk::operations::lifecycle::LifecycleInstance>,
38}
39
40/* === Enums === */
41
42#[cfg(feature = "lifecycle")]
43#[derive(Debug, thiserror::Error)]
44pub enum ControlError {
45    #[error(transparent)]
46    Dependency(#[from] harmos_sdk::ResourceError),
47    #[error("plugin lifecycle access failed: {0}")]
48    Access(#[source] harmos_sdk::operations::access::AccessError),
49}
50
51/* === Traits === */
52
53/* === Implementations === */
54
55harmos_domain::postcard_product!(Initialize { config_json: Vec<u8>, generation_context: Vec<u8>, assignments: Vec<u8> });
56impl Described for Initialize {
57    const NAME: &'static str = <harmos_domain::model::operations::lifecycle::InitializationSchema as Described>::NAME;
58    const FIELDS: &'static [harmos_domain::schema::declaration::Field] =
59        <harmos_domain::model::operations::lifecycle::InitializationSchema as Described>::FIELDS;
60    const MARKER: &'static [u8] = <harmos_domain::model::operations::lifecycle::InitializationSchema as Described>::MARKER;
61}
62
63impl MemorySize for Initialize {
64    fn memory_size(&self) -> usize {
65        std::mem::size_of::<Self>()
66            .saturating_add(self.config_json.capacity())
67            .saturating_add(self.generation_context.capacity())
68            .saturating_add(self.assignments.capacity())
69    }
70}
71
72#[cfg(feature = "lifecycle")]
73impl harmos_sdk::operations::Carrier for Control {
74    type Declaration = Initialize;
75    type Error = super::ControlError;
76    type StreamEndpoints = ();
77    async fn bind(context: crate::ExecutionContext) -> Result<Self, Self::Error> {
78        let access = context.resource::<harmos_sdk::operations::lifecycle::LifecycleAccess>()?;
79        Ok(Self {
80            instance: access.0.clone().begin(super::Action::Initialize),
81        })
82    }
83    async fn attempt(
84        &mut self, context: crate::ExecutionContext, request: &mut Initialize, _: &mut (),
85    ) -> Result<crate::Response<()>, Self::Error> {
86        let _ = &request;
87        self.instance
88            .run(context, &request.config_json, &request.generation_context, &request.assignments)
89            .await
90            .map_err(super::ControlError::Access)?;
91        Ok(().into())
92    }
93    async fn cleanup(&mut self) -> Result<(), Self::Error> {
94        self.instance.cleanup().await.map_err(super::ControlError::Access)
95    }
96}
97
98/* === Public Functions === */
99
100/* === Private Functions === */
101
102/* === Tests === */
103
104#[cfg(feature = "lifecycle")]
105impl crate::Executable for Initialize {
106    type Carrier = Control;
107}