application/
application.rs1use hydra::Application;
2use hydra::ExitReason;
3use hydra::From;
4use hydra::GenServer;
5use hydra::GenServerOptions;
6use hydra::Pid;
7
8use serde::Deserialize;
9use serde::Serialize;
10
11#[derive(Debug, Serialize, Deserialize)]
12enum StackMessage {
13 Pop,
14 PopResult(String),
15 Push(String),
16}
17
18struct Stack {
19 stack: Vec<String>,
20}
21
22impl Stack {
23 pub fn with_entries(entries: Vec<&'static str>) -> Self {
24 Self {
25 stack: Vec::from_iter(entries.into_iter().map(Into::into)),
26 }
27 }
28}
29
30impl GenServer for Stack {
31 type Message = StackMessage;
32
33 async fn init(&mut self) -> Result<(), ExitReason> {
34 Ok(())
35 }
36
37 async fn handle_call(
38 &mut self,
39 message: Self::Message,
40 _from: From,
41 ) -> Result<Option<Self::Message>, ExitReason> {
42 match message {
43 StackMessage::Pop => Ok(Some(StackMessage::PopResult(self.stack.remove(0)))),
44 _ => unreachable!(),
45 }
46 }
47
48 async fn handle_cast(&mut self, message: Self::Message) -> Result<(), ExitReason> {
49 match message {
50 StackMessage::Push(value) => self.stack.insert(0, value),
51 _ => unreachable!(),
52 }
53 Ok(())
54 }
55}
56
57struct StackApplication;
58
59impl Application for StackApplication {
60 async fn start(&self) -> Result<Pid, ExitReason> {
62 let pid = Stack::with_entries(vec!["hello", "world"])
63 .start_link(GenServerOptions::new())
64 .await
65 .expect("Failed to start stack!");
66
67 let result = Stack::call(pid, StackMessage::Pop, None)
68 .await
69 .expect("Stack call failed!");
70
71 tracing::info!("{:?}", result);
72
73 Stack::cast(pid, StackMessage::Push(String::from("rust")));
74
75 let result = Stack::call(pid, StackMessage::Pop, None)
76 .await
77 .expect("Stack call failed!");
78
79 tracing::info!("{:?}", result);
80
81 Stack::stop(pid, ExitReason::Normal, None).await?;
83
84 Ok(pid)
85 }
86}
87
88fn main() {
89 Application::run(StackApplication)
91}