result.rs (3119B)
1 use std::fmt::Debug; 2 3 use serde::Serialize; 4 use serde_json::Value; 5 6 use super::error::OperationAdapterError; 7 use super::request::OperationData; 8 use crate::out::envelope::{ 9 EnvelopeContext, NextAction, OutputEnvelope, OutputWarning, next_actions_from_result_value, 10 }; 11 use crate::registry::{OperationSpec, get_operation}; 12 13 pub trait OperationResultPayload: Debug + Clone + PartialEq + Serialize + 'static { 14 const OPERATION_ID: &'static str; 15 const RESULT_TYPE: &'static str; 16 } 17 18 pub trait OperationResultData: OperationResultPayload + Sized { 19 fn from_data(data: OperationData) -> Self; 20 21 fn from_value(value: Value) -> Self { 22 Self::from_data(value_to_data(value)) 23 } 24 25 fn from_serializable<T: Serialize>(value: &T) -> Result<Self, OperationAdapterError> { 26 Ok(Self::from_value(serde_json::to_value(value).map_err( 27 |error| OperationAdapterError::Serialization(error.to_string()), 28 )?)) 29 } 30 } 31 32 #[derive(Debug, Clone, PartialEq)] 33 pub struct OperationResult<P: OperationResultPayload> { 34 pub spec: &'static OperationSpec, 35 pub payload: P, 36 pub warnings: Vec<OutputWarning>, 37 pub next_actions: Vec<NextAction>, 38 } 39 40 impl<P: OperationResultPayload> OperationResult<P> { 41 pub fn new(payload: P) -> Result<Self, OperationAdapterError> { 42 let spec = get_operation(P::OPERATION_ID) 43 .ok_or_else(|| OperationAdapterError::UnknownOperation(P::OPERATION_ID.to_owned()))?; 44 if spec.rust_result != P::RESULT_TYPE { 45 return Err(OperationAdapterError::ResultTypeMismatch { 46 operation_id: P::OPERATION_ID.to_owned(), 47 registry_result: spec.rust_result.to_owned(), 48 adapter_result: P::RESULT_TYPE.to_owned(), 49 }); 50 } 51 Ok(Self { 52 spec, 53 payload, 54 warnings: Vec::new(), 55 next_actions: Vec::new(), 56 }) 57 } 58 59 pub fn operation_id(&self) -> &'static str { 60 P::OPERATION_ID 61 } 62 63 pub fn result_type_name(&self) -> &'static str { 64 P::RESULT_TYPE 65 } 66 67 pub fn to_envelope( 68 &self, 69 context: EnvelopeContext, 70 ) -> Result<OutputEnvelope, OperationAdapterError> { 71 let result = serde_json::to_value(&self.payload) 72 .map_err(|error| OperationAdapterError::Serialization(error.to_string()))?; 73 let next_actions = if self.next_actions.is_empty() { 74 next_actions_from_result(&result) 75 } else { 76 self.next_actions.clone() 77 }; 78 let mut envelope = OutputEnvelope::success(self.operation_id(), result, context); 79 envelope.warnings = self.warnings.clone(); 80 envelope.next_actions = next_actions; 81 Ok(envelope) 82 } 83 } 84 85 fn next_actions_from_result(result: &Value) -> Vec<NextAction> { 86 next_actions_from_result_value(result) 87 } 88 89 pub(crate) fn value_to_data(value: Value) -> OperationData { 90 match value { 91 Value::Object(map) => map, 92 other => { 93 let mut map = OperationData::new(); 94 map.insert("value".to_owned(), other); 95 map 96 } 97 } 98 }