rullst-core 12.3.0

Core runtime, routing engine, and telemetry for the Rullst framework suite.
Documentation
//! Event dispatch generated by `#[live_component]`.

use crate::live::LiveComponent;
use serde_json::json;

#[derive(Default)]
struct Chat {
    sent: usize,
    cleared: usize,
    withdrawn: usize,
}

#[crate::live_component]
impl Chat {
    #[live_event]
    fn send(&mut self) {
        self.sent += 1;
    }

    #[live_event]
    fn clear(&mut self) {
        self.cleared += 1;
    }

    #[live_event]
    async fn withdraw(&mut self, _payload: serde_json::Value) {
        self.withdrawn += 1;
    }

    pub fn render(&self) -> String {
        format!(
            "<div id=\"chat\">{} {} {}</div>",
            self.sent, self.cleared, self.withdrawn
        )
    }
}

impl Chat {
    fn counts(&self) -> (usize, usize, usize) {
        (self.sent, self.cleared, self.withdrawn)
    }
}

#[tokio::test]
async fn only_the_explicit_event_field_selects_one_handler() {
    let mut chat = Chat::default();

    // A form field whose value names another handler does not run it.
    chat.handle_event(json!({"rullst_event": "send", "message": "clear"}))
        .await;
    assert_eq!(chat.counts(), (1, 0, 0));

    // Without an event field, payload keys and string values never dispatch.
    chat.handle_event(json!({"send": "", "message": "clear"}))
        .await;
    chat.handle_event(json!({"a": "withdraw", "b": "withdraw", "withdraw": "x"}))
        .await;
    assert_eq!(chat.counts(), (1, 0, 0));

    // `action` and `event` remain explicit fields; each message runs once.
    chat.handle_event(json!({"action": "withdraw"})).await;
    chat.handle_event(json!({"event": "clear", "send": "send"}))
        .await;
    assert_eq!(chat.counts(), (1, 1, 1));

    // A non-string event field and unknown event names dispatch nothing.
    chat.handle_event(json!({"rullst_event": 1, "send": "send"}))
        .await;
    chat.handle_event(json!({"rullst_event": "unknown", "clear": "clear"}))
        .await;
    chat.handle_event(json!(["send", "clear"])).await;
    assert_eq!(chat.counts(), (1, 1, 1));
    assert_eq!(LiveComponent::render(&chat), "<div id=\"chat\">1 1 1</div>");
}