Skip to main content

harmos_domain/operations/lifecycle/
instance.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
16// Standard Library Imports
17
18// Third Party Imports
19
20// Local Imports
21use super::{Cancel, InstanceState, Status, Watch};
22use crate::operations::instance::{self, Id, Outcome, Phase};
23use crate::operations::{OperationPolicy, Visibility};
24
25/* === Constants === */
26
27// A watch lasts until its instance settles or the caller cancels it.
28const WATCH_POLICY: OperationPolicy = OperationPolicy {
29    timeout: crate::operations::UNBOUNDED,
30    attempt_timeout: crate::operations::UNBOUNDED,
31    ..crate::operations::host::POLICY
32};
33
34/* === Macros === */
35
36crate::declare!(Status {
37    id: "host.operations.status",
38    version: 1,
39    policy: crate::operations::host::POLICY,
40    response: InstanceState,
41    description: "Report the status of an operation instance the caller submitted",
42    visibility: Visibility::Shared,
43    grpc: ("harmos.host.v1", "Operations", "Status"),
44});
45
46crate::declare!(Cancel {
47    id: "host.operations.cancel",
48    version: 1,
49    policy: crate::operations::host::POLICY,
50    response: InstanceState,
51    description: "Request cancellation of an operation instance the caller submitted",
52    visibility: Visibility::Shared,
53    grpc: ("harmos.host.v1", "Operations", "Cancel"),
54});
55
56crate::declare!(Watch {
57    id: "host.operations.watch",
58    version: 1,
59    policy: WATCH_POLICY,
60    response: InstanceState,
61    output: InstanceState,
62    description: "Stream the status changes of an operation instance the caller submitted until it settles",
63    visibility: Visibility::Shared,
64    grpc: ("harmos.host.v1", "Operations", "Watch"),
65});
66
67/* === Type Aliases === */
68
69/* === Structs === */
70
71/* === Enums === */
72
73/* === Traits === */
74
75/* === Implementations === */
76
77impl Status {
78    pub fn of(instance: Id) -> Self {
79        Self { instance: instance.value() }
80    }
81}
82
83impl Watch {
84    pub fn of(instance: Id) -> Self {
85        Self { instance: instance.value() }
86    }
87}
88
89impl Cancel {
90    pub fn of(instance: Id) -> Self {
91        Self { instance: instance.value() }
92    }
93}
94
95impl From<instance::Status> for InstanceState {
96    fn from(status: instance::Status) -> Self {
97        Self {
98            phase: status.phase.as_str().to_owned(),
99            outcome: status.outcome.map(Outcome::as_str).unwrap_or_default().to_owned(),
100            cancellation_requested: status.cancellation_requested,
101            attempt: status.attempt,
102        }
103    }
104}
105
106impl TryFrom<&InstanceState> for instance::Status {
107    type Error = instance::ParseError;
108
109    fn try_from(state: &InstanceState) -> Result<Self, Self::Error> {
110        let phase = state.phase.parse::<Phase>()?;
111        let outcome = match state.outcome.as_str() {
112            "" => None,
113            outcome => Some(outcome.parse::<Outcome>()?),
114        };
115        Ok(Self { phase, outcome, cancellation_requested: state.cancellation_requested, attempt: state.attempt })
116    }
117}
118
119/* === Public Functions === */
120
121/* === Private Functions === */
122
123/* === Tests === */