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