rings_node/extension/protocols/
echo.rs1use bytes::Bytes;
13use rings_core::dht::Did;
14
15use crate::extension::ext::Ctx;
16use crate::extension::ext::EffectScope;
17use crate::extension::ext::Interpret;
18use crate::extension::ext::Protocol;
19use crate::extension::ext::Reject;
20use crate::extension::ext::Transition;
21use crate::extension::ext::Wire;
22
23pub const NAMESPACE: &str = "echo";
25
26#[derive(Clone, Debug, PartialEq, Eq)]
28pub struct Echoed {
29 pub from: Did,
31 pub payload: Bytes,
33}
34
35#[derive(Clone, Debug, PartialEq, Eq)]
37pub enum EchoEffect {
38 Reply {
40 to: Did,
42 payload: Bytes,
44 },
45}
46
47#[derive(Default)]
49pub struct Echo;
50
51impl Protocol for Echo {
52 type State = u64;
54 type Event = Echoed;
55 type Effect = EchoEffect;
56
57 fn namespace(&self) -> &str {
58 NAMESPACE
59 }
60
61 fn init(&self) -> u64 {
62 0
63 }
64
65 fn decode(&self, wire: Wire<'_>) -> Result<Echoed, Reject> {
66 Ok(Echoed {
67 from: wire.from,
68 payload: Bytes::copy_from_slice(wire.payload),
69 })
70 }
71
72 fn step(&self, ctx: Ctx<'_, u64>, event: Echoed) -> Transition<u64, EchoEffect> {
74 Transition::with(ctx.state + 1, vec![EchoEffect::Reply {
75 to: event.from,
76 payload: event.payload,
77 }])
78 }
79}
80
81#[derive(Default)]
83pub struct EchoShell;
84
85#[cfg_attr(rings_browser, async_trait::async_trait(?Send))]
86#[cfg_attr(rings_native, async_trait::async_trait)]
87impl Interpret for EchoShell {
88 type Effect = EchoEffect;
89
90 async fn run(
91 &self,
92 scope: &EffectScope,
93 effect: EchoEffect,
94 ) -> crate::error::Result<Vec<Bytes>> {
95 match effect {
96 EchoEffect::Reply { to, payload } => {
97 scope.send(to, payload).await?;
98 Ok(Vec::new())
99 }
100 }
101 }
102}