Concepts

Data

Everything that crosses the hook boundary is a rustmc_plugin::hook::Data, which has the shape of JSON:

pub enum Data { Null, Bool(bool), Int(i64), Float(f64), Str(String), List(Vec<Data>), Map(BTreeMap<String, Data>) }

A Wasm guest receives exactly this tree as JSON, and its JSON answer becomes this tree. A Rust plugin and a Wasm plugin therefore see the same field names and the same values.

Typed records

A hook point declares its input and output as plain structs with record!:

rustmc_plugin::record! {
    pub struct CommandHook {
        pub name: String,
        pub rest: String,
    }
}

This derives HookData, which converts both ways:

let typed = CommandHook::from_data(call.input).expect("the command hook's input");

Conversion rules:

Rust typeDataNotes
boolBool
integersInta whole Float is accepted (3.0 → 3); an out-of-range value is refused, not wrapped
f32, f64Floatan Int is accepted
StringStr
Option<T>T or Nullthe field must still be present
Vec<T>, tuplesListtuples have a fixed length
BytesStr of lower-case hexpacket bodies
record! structMapevery field is required

A field you leave out is not a default. It makes the whole reply invalid, and the reply is refused.

Helpers

Data::get(field), Data::set(field, value), as_i64, as_f64, as_bool, as_str and as_list let a plugin edit an input without declaring a struct, as in the recipes.

From docs/api/concepts/data.md in the RustMC repository at bbd81209ad.