97 lines
2.3 KiB
Rust
97 lines
2.3 KiB
Rust
|
use lunatic::supervisor::{Supervisor, SupervisorConfig, SupervisorStrategy};
|
||
|
use serde::{Deserialize, Serialize};
|
||
|
use submillisecond::{router, static_router, Application};
|
||
|
use submillisecond_live_view::prelude::*;
|
||
|
|
||
|
use lunatic::abstract_process;
|
||
|
use lunatic::ap::{Config, ProcessRef};
|
||
|
|
||
|
pub struct Counter(i64);
|
||
|
|
||
|
#[abstract_process(visibility = pub)]
|
||
|
impl Counter {
|
||
|
#[init]
|
||
|
fn init(_: Config<Self>, start: i64) -> Result<Self, ()> {
|
||
|
Ok(Self(start))
|
||
|
}
|
||
|
|
||
|
#[handle_message]
|
||
|
fn increment(&mut self) {
|
||
|
self.0 += 1;
|
||
|
}
|
||
|
|
||
|
#[handle_message]
|
||
|
fn decrement(&mut self) {
|
||
|
self.0 -= 1;
|
||
|
}
|
||
|
|
||
|
#[handle_request]
|
||
|
fn count(&self) -> i64 {
|
||
|
self.0
|
||
|
}
|
||
|
}
|
||
|
|
||
|
struct Sup;
|
||
|
|
||
|
impl Supervisor for Sup {
|
||
|
type Arg = ();
|
||
|
// Start 1 child and monitor it for failures.
|
||
|
type Children = (Counter,);
|
||
|
|
||
|
fn init(config: &mut SupervisorConfig<Self>, _: ()) {
|
||
|
config.set_strategy(SupervisorStrategy::OneForOne);
|
||
|
config.children_args(((0, Some(String::from("global_counter"))),));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fn main() -> std::io::Result<()> {
|
||
|
let mut supconf = SupervisorConfig::default();
|
||
|
Sup::init(&mut supconf, ());
|
||
|
|
||
|
Application::new(router! {
|
||
|
"/" => CounterView::handler("index.html", "#app")
|
||
|
"/static" => static_router!("./static")
|
||
|
})
|
||
|
.serve("127.0.0.1:3000")
|
||
|
}
|
||
|
|
||
|
#[derive(Clone, Serialize, Deserialize)]
|
||
|
struct CounterView {
|
||
|
global_counter: ProcessRef<Counter>,
|
||
|
}
|
||
|
|
||
|
impl LiveView for CounterView {
|
||
|
type Events = (Increment, Decrement);
|
||
|
|
||
|
fn mount(_uri: Uri, _socket: Option<Socket>) -> Self {
|
||
|
let global_counter = ProcessRef::<Counter>::lookup(&"global_counter").unwrap();
|
||
|
Self { global_counter }
|
||
|
}
|
||
|
|
||
|
fn render(&self) -> Rendered {
|
||
|
html! {
|
||
|
button @click=(Increment) { "Increment" }
|
||
|
button @click=(Decrement) { "Decrement" }
|
||
|
p { "Count is " (self.global_counter.count()) }
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[derive(Deserialize)]
|
||
|
struct Increment {}
|
||
|
|
||
|
impl LiveViewEvent<Increment> for CounterView {
|
||
|
fn handle(state: &mut Self, _event: Increment) {
|
||
|
state.global_counter.increment()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[derive(Deserialize)]
|
||
|
struct Decrement {}
|
||
|
|
||
|
impl LiveViewEvent<Decrement> for CounterView {
|
||
|
fn handle(state: &mut Self, _event: Decrement) {
|
||
|
state.global_counter.decrement()
|
||
|
}
|
||
|
}
|