Expand description
#[derive(Message)]: a Rust enum or struct to and from the plain-data
payload a kui message is.
kui carries every message as a Value map shaped {kind, ...fields},
so one view model serves Rust, Lua, C and Node alike. This derive lets a
Rust app keep a typed enum instead of building and picking apart those
maps by string: widgets::button(ui, "Save", Msg::Save) sends it and
ev.message::<Msg>() reads it back. Most apps get the derive through
kui-native (use kui_native::Message; cargo feature derive, on by
default) and never name this crate.
§Example
The generated code reaches kui through kui_native, which this crate
does not depend on, so the example is not compiled here.
use kui_native::widgets;
use kui_native::{App, Message, NodeSpec, Ui, UiEvent};
#[derive(Message, Clone, Debug, PartialEq)]
enum Msg {
Inc, // {kind: "inc"}
Pick { id: u64 }, // {kind: "pick", id: 3}
#[message(kind = "add10")]
AddTen, // {kind: "add10"}
}
#[derive(Default)]
struct Counter {
count: i64,
}
impl App for Counter {
fn view(&mut self, ui: &mut Ui<'_>) {
ui.with(NodeSpec::row().gap(8.0), |ui| {
widgets::button(ui, "+1", Msg::Inc);
widgets::button(ui, "+10", Msg::AddTen);
});
}
fn on_event(&mut self, ev: UiEvent) {
match ev.message::<Msg>() {
Some(Msg::Inc) => self.count += 1,
Some(Msg::AddTen) => self.count += 10,
Some(Msg::Pick { id }) => println!("picked {id}"),
None => {} // not a `Msg`: a resize, a focus change
}
}
}§What it generates
For a type Msg:
From<Msg> for Value: a map whosekindis the variant’s name in snake_case (TabNewis"tab_new"; a struct uses its own name) and whose other keys are the fields, a tuple variant’s by position ("0","1", …).TryFrom<&Value>andTryFrom<Value> for Msg, withMessageErrorsaying what did not fit.MessageField for Msg, so a message can be a field of another.
A field is anything that implements MessageField: bool, the
numbers, String, Option<T>, Vec<T>, Box<T>, Value and other
messages.
§Attributes
All under #[message(...)]:
- on a variant or a struct,
kind = "..."names itskindinstead of the snake_case name; - on an enum of unit variants only,
stringmakes it a bare string ("h") rather than a map ({kind: "h"}), which reads best for a field such as a split’s direction; - on the type,
crate = "..."names the path the generated code reaches kui through:::kui_nativeunless said,kui_corefor a crate that depends on kui-core alone.
#[derive(Message, Clone, Copy, Debug, PartialEq)]
#[message(string)]
enum Dir { H, V } // "h" / "v"
#[derive(Message, Clone, Debug, PartialEq)]
#[message(crate = "kui_core")]
struct Resize { w: f64, h: f64 } // {kind: "resize", w, h}The book: https://kui-book.qxuken.dev. Repository: https://github.com/qxuken/kui.
Derive Macros§
- Message
- Derives
From<Self> for Value,TryFrom<&Value>,TryFrom<Value>andMessageFieldfor an enum or a struct; see the crate docs.