Skip to main content

actrpc_core/action/
resolved_action.rs

1use crate::{
2    action::{ActionSpec, ResolvedActionRecord},
3    error::ActionCodecError,
4};
5
6/// The orchestrator’s recorded outcome for a previously requested action.
7/// If the interceptor is reinvoked, this is fed back into subsequent
8/// interceptor invocations.
9#[derive(Debug, Clone, PartialEq)]
10pub struct ResolvedAction<A: ActionSpec> {
11    pub params: A::Params,
12    pub result: Result<A::Result, crate::error::ProtocolError>,
13}
14
15impl<A> ResolvedAction<A>
16where
17    A: ActionSpec,
18{
19    fn decode_from_record(value: &ResolvedActionRecord) -> Result<Self, ActionCodecError> {
20        let expected = A::action_kind();
21
22        if value.kind != expected {
23            return Err(ActionCodecError::KindMismatch {
24                expected,
25                actual: value.kind.clone(),
26            });
27        }
28
29        let raw_params = value
30            .params
31            .clone()
32            .ok_or_else(|| ActionCodecError::MissingParams {
33                action: value.kind.clone(),
34            })?;
35
36        let params = serde_json::from_value(raw_params).map_err(|source| {
37            ActionCodecError::InvalidParams {
38                action: value.kind.clone(),
39                source,
40            }
41        })?;
42
43        let result = match &value.result {
44            Ok(Some(v)) => Ok(serde_json::from_value(v.clone()).map_err(|source| {
45                ActionCodecError::InvalidResult {
46                    action: value.kind.clone(),
47                    source,
48                }
49            })?),
50            Ok(None) => {
51                return Err(ActionCodecError::MissingOkResult {
52                    action: value.kind.clone(),
53                });
54            }
55            Err(err) => Err(err.clone()),
56        };
57
58        Ok(Self { params, result })
59    }
60}
61
62impl<A> TryFrom<ResolvedActionRecord> for ResolvedAction<A>
63where
64    A: ActionSpec,
65{
66    type Error = ActionCodecError;
67
68    fn try_from(value: ResolvedActionRecord) -> Result<Self, Self::Error> {
69        Self::decode_from_record(&value)
70    }
71}