Skip to main content

aura_composition/adapters/
time.rs

1//! Time handler adapter
2
3use crate::adapters::collect_ops;
4use crate::adapters::utils::{deserialize_operation_params, serialize_operation_result};
5use crate::registry::{HandlerContext, HandlerError, RegistrableHandler};
6use async_trait::async_trait;
7use aura_core::effects::{LogicalClockEffects, OrderClockEffects, PhysicalTimeEffects};
8use aura_core::{EffectType, ExecutionMode};
9use aura_effects::time::PhysicalTimeHandler;
10
11/// Adapter for PhysicalTimeHandler (domain-specific time effects)
12pub struct TimeHandlerAdapter {
13    physical: PhysicalTimeHandler,
14    #[allow(deprecated)]
15    logical: aura_effects::time::LogicalClockHandler,
16    order: aura_effects::time::OrderClockHandler,
17}
18
19impl TimeHandlerAdapter {
20    pub fn new(handler: PhysicalTimeHandler) -> Self {
21        Self {
22            physical: handler,
23            #[allow(deprecated)]
24            logical: aura_effects::time::LogicalClockHandler::new(),
25            order: aura_effects::time::OrderClockHandler,
26        }
27    }
28}
29
30#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
31#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
32impl RegistrableHandler for TimeHandlerAdapter {
33    async fn execute_operation_bytes(
34        &self,
35        effect_type: EffectType,
36        operation: &str,
37        parameters: &[u8],
38        _ctx: &HandlerContext,
39    ) -> Result<Vec<u8>, HandlerError> {
40        if effect_type != EffectType::Time {
41            return Err(HandlerError::UnsupportedEffect { effect_type });
42        }
43
44        match operation {
45            "physical_time" => {
46                let result = self.physical.physical_time().await.map_err(|e| {
47                    HandlerError::ExecutionFailed {
48                        source: Box::new(e),
49                    }
50                })?;
51                serialize_operation_result(effect_type, operation, &result)
52            }
53            "sleep_ms" => {
54                let millis: u64 = deserialize_operation_params(effect_type, operation, parameters)?;
55                let _ = PhysicalTimeEffects::sleep_ms(&self.physical, millis).await;
56                Ok(Vec::new()) // sleep returns void
57            }
58            "sleep_until" => {
59                let epoch: u64 = deserialize_operation_params(effect_type, operation, parameters)?;
60                self.physical.sleep_until(epoch).await;
61                Ok(Vec::new())
62            }
63            "logical_advance" => {
64                let observed: Option<aura_core::time::VectorClock> =
65                    deserialize_operation_params(effect_type, operation, parameters)?;
66                let result = self
67                    .logical
68                    .logical_advance(observed.as_ref())
69                    .await
70                    .map_err(|e| HandlerError::ExecutionFailed {
71                        source: Box::new(e),
72                    })?;
73                serialize_operation_result(effect_type, operation, &result)
74            }
75            "logical_now" => {
76                let result = self.logical.logical_now().await.map_err(|e| {
77                    HandlerError::ExecutionFailed {
78                        source: Box::new(e),
79                    }
80                })?;
81                serialize_operation_result(effect_type, operation, &result)
82            }
83            "order_time" => {
84                let result =
85                    self.order
86                        .order_time()
87                        .await
88                        .map_err(|e| HandlerError::ExecutionFailed {
89                            source: Box::new(e),
90                        })?;
91                serialize_operation_result(effect_type, operation, &result)
92            }
93            _ => Err(HandlerError::UnknownOperation {
94                effect_type,
95                operation: operation.to_string(),
96            }),
97        }
98    }
99
100    fn supported_operations(&self, effect_type: EffectType) -> Vec<String> {
101        collect_ops(effect_type, false) // Time has no extended operations
102    }
103
104    fn supports_effect(&self, effect_type: EffectType) -> bool {
105        effect_type == EffectType::Time
106    }
107
108    fn execution_mode(&self) -> ExecutionMode {
109        ExecutionMode::Production
110    }
111}