chore(plugin-api): enable enable_method_chaining

This commit is contained in:
Alexander Medvedev 2026-04-17 20:54:36 +02:00
parent fa833ba439
commit 2b4e3bb332
5 changed files with 131 additions and 96 deletions

90
Cargo.lock generated
View File

@ -1542,6 +1542,11 @@ name = "hashbrown"
version = "0.17.0" version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51"
dependencies = [
"foldhash 0.2.0",
"serde",
"serde_core",
]
[[package]] [[package]]
name = "hdrhistogram" name = "hdrhistogram"
@ -2868,7 +2873,7 @@ dependencies = [
"tracing-subscriber", "tracing-subscriber",
"ureq", "ureq",
"uuid", "uuid",
"wasmparser 0.246.2", "wasmparser 0.247.0",
"wasmtime", "wasmtime",
"wasmtime-wasi", "wasmtime-wasi",
] ]
@ -2962,7 +2967,7 @@ dependencies = [
"postcard", "postcard",
"tracing", "tracing",
"tracing-serde-structured", "tracing-serde-structured",
"wit-bindgen 0.56.0", "wit-bindgen 0.57.1",
] ]
[[package]] [[package]]
@ -4474,6 +4479,16 @@ dependencies = [
"wasmparser 0.246.2", "wasmparser 0.246.2",
] ]
[[package]]
name = "wasm-encoder"
version = "0.247.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30b6733b8b91d010a6ac5b0fb237dc46a19650bc4c67db66857e2e787d437204"
dependencies = [
"leb128fmt",
"wasmparser 0.247.0",
]
[[package]] [[package]]
name = "wasm-metadata" name = "wasm-metadata"
version = "0.244.0" version = "0.244.0"
@ -4488,14 +4503,14 @@ dependencies = [
[[package]] [[package]]
name = "wasm-metadata" name = "wasm-metadata"
version = "0.246.2" version = "0.247.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3e4c2aa916c425dcca61a6887d3e135acdee2c6d0ed51fd61c08d41ddaf62b1" checksum = "665fe59e56cc9b419ca6fcca56673e3421d1a5011e3b65caf6b726fd9e041d10"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"indexmap", "indexmap",
"wasm-encoder 0.246.2", "wasm-encoder 0.247.0",
"wasmparser 0.246.2", "wasmparser 0.247.0",
] ]
[[package]] [[package]]
@ -4530,7 +4545,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71cde4757396defafd25417cfb36aa3161027d06d865b0c24baaae229aac005d" checksum = "71cde4757396defafd25417cfb36aa3161027d06d865b0c24baaae229aac005d"
dependencies = [ dependencies = [
"bitflags 2.11.1", "bitflags 2.11.1",
"hashbrown 0.16.1", "indexmap",
"semver",
]
[[package]]
name = "wasmparser"
version = "0.247.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e6fb4c2bee46c5ea4d40f8cdb5c131725cd976718ec56f1c8e82fbde5fa2a80"
dependencies = [
"bitflags 2.11.1",
"hashbrown 0.17.0",
"indexmap", "indexmap",
"semver", "semver",
"serde", "serde",
@ -5285,12 +5311,12 @@ dependencies = [
[[package]] [[package]]
name = "wit-bindgen" name = "wit-bindgen"
version = "0.56.0" version = "0.57.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7607d30e7e5e8fd5a0695f7cb8b2128829e0bf9dca7a1fe8c4d6ed3ca1058fce" checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e"
dependencies = [ dependencies = [
"bitflags 2.11.1", "bitflags 2.11.1",
"wit-bindgen-rust-macro 0.56.0", "wit-bindgen-rust-macro 0.57.1",
] ]
[[package]] [[package]]
@ -5306,13 +5332,13 @@ dependencies = [
[[package]] [[package]]
name = "wit-bindgen-core" name = "wit-bindgen-core"
version = "0.56.0" version = "0.57.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fda3a4ce47c08d27f575d451a60102bab5251776abd0a7a323d1f038eb6339ab" checksum = "02dee27a2dc20d1008016c742ec9fc6ea498492994ba3750be7454cbc97ff04c"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"heck", "heck",
"wit-parser 0.246.2", "wit-parser 0.247.0",
] ]
[[package]] [[package]]
@ -5333,18 +5359,18 @@ dependencies = [
[[package]] [[package]]
name = "wit-bindgen-rust" name = "wit-bindgen-rust"
version = "0.56.0" version = "0.57.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "920a1c8c0f89397431db4900a7bf7c511b78e1b7068289fe812dc76e993f1491" checksum = "b5007dae772945b7a5003d69d90a3a4a78929d41f19d004e980c4259a6af4484"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"heck", "heck",
"indexmap", "indexmap",
"prettyplease", "prettyplease",
"syn", "syn",
"wasm-metadata 0.246.2", "wasm-metadata 0.247.0",
"wit-bindgen-core 0.56.0", "wit-bindgen-core 0.57.1",
"wit-component 0.246.2", "wit-component 0.247.0",
] ]
[[package]] [[package]]
@ -5364,9 +5390,9 @@ dependencies = [
[[package]] [[package]]
name = "wit-bindgen-rust-macro" name = "wit-bindgen-rust-macro"
version = "0.56.0" version = "0.57.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "857a143d2373abfcd31ad946393efe775ed8c90a2a365ce73c61bf38f36a1000" checksum = "af9237d678e3513ad24e96fe98beacdc0db6405284ba2a2400418cf0d42caa89"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"macro-string", "macro-string",
@ -5374,8 +5400,8 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn",
"wit-bindgen-core 0.56.0", "wit-bindgen-core 0.57.1",
"wit-bindgen-rust 0.56.0", "wit-bindgen-rust 0.57.1",
] ]
[[package]] [[package]]
@ -5399,9 +5425,9 @@ dependencies = [
[[package]] [[package]]
name = "wit-component" name = "wit-component"
version = "0.246.2" version = "0.247.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1936c26cb24b93dc36bf78fb5dc35c55cd37f66ecdc2d2663a717d9fb3ee951e" checksum = "9d567162a6b9843080e5e0053f696623ff694bae8ae017c9ec536d1873bbe3d8"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bitflags 2.11.1", "bitflags 2.11.1",
@ -5410,10 +5436,10 @@ dependencies = [
"serde", "serde",
"serde_derive", "serde_derive",
"serde_json", "serde_json",
"wasm-encoder 0.246.2", "wasm-encoder 0.247.0",
"wasm-metadata 0.246.2", "wasm-metadata 0.247.0",
"wasmparser 0.246.2", "wasmparser 0.247.0",
"wit-parser 0.246.2", "wit-parser 0.247.0",
] ]
[[package]] [[package]]
@ -5455,12 +5481,12 @@ dependencies = [
[[package]] [[package]]
name = "wit-parser" name = "wit-parser"
version = "0.246.2" version = "0.247.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd979042b5ff288607ccf3b314145435453f20fc67173195f91062d2289b204d" checksum = "8ffe4064318cdf3c08cb99343b44c039fcefe61ccdf58aa9975285f13d74d1fc"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"hashbrown 0.16.1", "hashbrown 0.17.0",
"id-arena", "id-arena",
"indexmap", "indexmap",
"log", "log",
@ -5469,7 +5495,7 @@ dependencies = [
"serde_derive", "serde_derive",
"serde_json", "serde_json",
"unicode-xid", "unicode-xid",
"wasmparser 0.246.2", "wasmparser 0.247.0",
] ]
[[package]] [[package]]

View File

@ -180,8 +180,8 @@ notify = "8.2.0"
wasmtime = "43.0" wasmtime = "43.0"
wasmtime-wasi = "43.0" wasmtime-wasi = "43.0"
wit-bindgen = "0.56" wit-bindgen = "0.57"
wasmparser = "0.246" wasmparser = "0.247"
postcard = { version = "1.1", features = ["alloc"] } postcard = { version = "1.1", features = ["alloc"] }
tracing-serde-structured = "0.4" tracing-serde-structured = "0.4"

View File

@ -56,6 +56,7 @@ mod wit {
skip: ["init-plugin"], skip: ["init-plugin"],
path: "../pumpkin-plugin-wit/v0.1.0", path: "../pumpkin-plugin-wit/v0.1.0",
world: "plugin", world: "plugin",
enable_method_chaining: true
}); });
use super::Component; use super::Component;

View File

@ -5,37 +5,34 @@ interface text {
text: static func(plain: string) -> text-component; text: static func(plain: string) -> text-component;
translate: static func(key: string, %with: list<text-component>) -> text-component; translate: static func(key: string, %with: list<text-component>) -> text-component;
add-child: func(child: text-component); add-child: func(child: text-component) -> text-component;
add-text: func(text: string); add-text: func(text: string) -> text-component;
get-text: func() -> string; get-text: func() -> string;
encode: func() -> list<u8>; encode: func() -> list<u8>;
// Style // Style
color-named: func(color: named-color) -> text-component;
color-named: func(color: named-color); color-rgb: func(color: rgb-color) -> text-component;
color-rgb: func(color: rgb-color); bold: func(value: bool) -> text-component;
bold: func(value: bool); italic: func(value: bool) -> text-component;
italic: func(value: bool); underlined: func(value: bool) -> text-component;
underlined: func(value: bool); strikethrough: func(value: bool) -> text-component;
strikethrough: func(value: bool); obfuscated: func(value: bool) -> text-component;
obfuscated: func(value: bool);
/// Text inserted into chat when shift-clicked /// Text inserted into chat when shift-clicked
insertion: func(text: string); insertion: func(text: string) -> text-component;
font: func(font: string); font: func(font: string) -> text-component;
shadow-color: func(color: argb-color); shadow-color: func(color: argb-color) -> text-component;
// Click events // Click events
click-open-url: func(url: string) -> text-component;
click-open-url: func(url: string); click-run-command: func(command: string) -> text-component;
click-run-command: func(command: string); click-suggest-command: func(command: string) -> text-component;
click-suggest-command: func(command: string); click-copy-to-clipboard: func(text: string) -> text-component;
click-copy-to-clipboard: func(text: string);
// Hover events // Hover events
hover-show-text: func(text: text-component) -> text-component;
hover-show-text: func(text: text-component);
/// Item data as SNBT string /// Item data as SNBT string
hover-show-item: func(item: string); hover-show-item: func(item: string) -> text-component;
hover-show-entity: func(entity-type: string, id: string, name: option<text-component>); hover-show-entity: func(entity-type: string, id: string, name: option<text-component>) -> text-component;
} }
} }

View File

@ -101,22 +101,21 @@ impl pumpkin::plugin::text::HostTextComponent for PluginHostState {
&mut self, &mut self,
text_component: Resource<TextComponent>, text_component: Resource<TextComponent>,
child: Resource<TextComponent>, child: Resource<TextComponent>,
) -> wasmtime::Result<()> { ) -> wasmtime::Result<Resource<TextComponent>> {
let child_tc = self.take_text(&child)?.provider; let child_tc = self.take_text(&child)?.provider;
let parent = self.get_text_mut(&text_component)?; let parent = self.get_text_mut(&text_component)?;
// Cloning here as noted in your TODO until builder pattern supports &mut self
parent.provider = parent.provider.clone().add_child(child_tc); parent.provider = parent.provider.clone().add_child(child_tc);
Ok(()) Ok(text_component)
} }
async fn add_text( async fn add_text(
&mut self, &mut self,
text_component: Resource<TextComponent>, text_component: Resource<TextComponent>,
text: String, text: String,
) -> wasmtime::Result<()> { ) -> wasmtime::Result<Resource<TextComponent>> {
let parent = self.get_text_mut(&text_component)?; let parent = self.get_text_mut(&text_component)?;
parent.provider = parent.provider.clone().add_text(text); parent.provider = parent.provider.clone().add_text(text);
Ok(()) Ok(text_component)
} }
async fn get_text( async fn get_text(
@ -145,149 +144,161 @@ impl pumpkin::plugin::text::HostTextComponent for PluginHostState {
&mut self, &mut self,
res: Resource<TextComponent>, res: Resource<TextComponent>,
color: NamedColor, color: NamedColor,
) -> wasmtime::Result<()> { ) -> wasmtime::Result<Resource<TextComponent>> {
self.get_text_mut(&res)?.provider.0.style.color = self.get_text_mut(&res)?.provider.0.style.color =
Some(Color::Named(map_named_color(color))); Some(Color::Named(map_named_color(color)));
Ok(()) Ok(res)
} }
async fn color_rgb( async fn color_rgb(
&mut self, &mut self,
res: Resource<TextComponent>, res: Resource<TextComponent>,
color: RgbColor, color: RgbColor,
) -> wasmtime::Result<()> { ) -> wasmtime::Result<Resource<TextComponent>> {
self.get_text_mut(&res)?.provider.0.style.color = self.get_text_mut(&res)?.provider.0.style.color =
Some(Color::Rgb(color::RGBColor::new(color.r, color.g, color.b))); Some(Color::Rgb(color::RGBColor::new(color.r, color.g, color.b)));
Ok(()) Ok(res)
} }
async fn bold(&mut self, res: Resource<TextComponent>, value: bool) -> wasmtime::Result<()> { async fn bold(
&mut self,
res: Resource<TextComponent>,
value: bool,
) -> wasmtime::Result<Resource<TextComponent>> {
self.get_text_mut(&res)?.provider.0.style.bold = Some(value); self.get_text_mut(&res)?.provider.0.style.bold = Some(value);
Ok(()) Ok(res)
} }
async fn italic(&mut self, res: Resource<TextComponent>, value: bool) -> wasmtime::Result<()> { async fn italic(
&mut self,
res: Resource<TextComponent>,
value: bool,
) -> wasmtime::Result<Resource<TextComponent>> {
self.get_text_mut(&res)?.provider.0.style.italic = Some(value); self.get_text_mut(&res)?.provider.0.style.italic = Some(value);
Ok(()) Ok(res)
} }
async fn underlined( async fn underlined(
&mut self, &mut self,
res: Resource<TextComponent>, res: Resource<TextComponent>,
value: bool, value: bool,
) -> wasmtime::Result<()> { ) -> wasmtime::Result<Resource<TextComponent>> {
self.get_text_mut(&res)?.provider.0.style.underlined = Some(value); self.get_text_mut(&res)?.provider.0.style.underlined = Some(value);
Ok(()) Ok(res)
} }
async fn strikethrough( async fn strikethrough(
&mut self, &mut self,
res: Resource<TextComponent>, res: Resource<TextComponent>,
value: bool, value: bool,
) -> wasmtime::Result<()> { ) -> wasmtime::Result<Resource<TextComponent>> {
self.get_text_mut(&res)?.provider.0.style.strikethrough = Some(value); self.get_text_mut(&res)?.provider.0.style.strikethrough = Some(value);
Ok(()) Ok(res)
} }
async fn obfuscated( async fn obfuscated(
&mut self, &mut self,
res: Resource<TextComponent>, res: Resource<TextComponent>,
value: bool, value: bool,
) -> wasmtime::Result<()> { ) -> wasmtime::Result<Resource<TextComponent>> {
self.get_text_mut(&res)?.provider.0.style.obfuscated = Some(value); self.get_text_mut(&res)?.provider.0.style.obfuscated = Some(value);
Ok(()) Ok(res)
} }
async fn insertion( async fn insertion(
&mut self, &mut self,
res: Resource<TextComponent>, res: Resource<TextComponent>,
text: String, text: String,
) -> wasmtime::Result<()> { ) -> wasmtime::Result<Resource<TextComponent>> {
self.get_text_mut(&res)?.provider.0.style.insertion = Some(text); self.get_text_mut(&res)?.provider.0.style.insertion = Some(text);
Ok(()) Ok(res)
} }
async fn font(&mut self, res: Resource<TextComponent>, font: String) -> wasmtime::Result<()> { async fn font(
&mut self,
res: Resource<TextComponent>,
font: String,
) -> wasmtime::Result<Resource<TextComponent>> {
self.get_text_mut(&res)?.provider.0.style.font = Some(font); self.get_text_mut(&res)?.provider.0.style.font = Some(font);
Ok(()) Ok(res)
} }
async fn shadow_color( async fn shadow_color(
&mut self, &mut self,
res: Resource<TextComponent>, res: Resource<TextComponent>,
color: ArgbColor, color: ArgbColor,
) -> wasmtime::Result<()> { ) -> wasmtime::Result<Resource<TextComponent>> {
self.get_text_mut(&res)?.provider.0.style.shadow_color = self.get_text_mut(&res)?.provider.0.style.shadow_color =
Some(color::ARGBColor::new(color.a, color.r, color.g, color.b)); Some(color::ARGBColor::new(color.a, color.r, color.g, color.b));
Ok(()) Ok(res)
} }
async fn click_open_url( async fn click_open_url(
&mut self, &mut self,
res: Resource<TextComponent>, res: Resource<TextComponent>,
url: String, url: String,
) -> wasmtime::Result<()> { ) -> wasmtime::Result<Resource<TextComponent>> {
self.get_text_mut(&res)?.provider.0.style.click_event = Some(ClickEvent::OpenUrl { self.get_text_mut(&res)?.provider.0.style.click_event = Some(ClickEvent::OpenUrl {
url: Cow::Owned(url), url: Cow::Owned(url),
}); });
Ok(()) Ok(res)
} }
async fn click_run_command( async fn click_run_command(
&mut self, &mut self,
res: Resource<TextComponent>, res: Resource<TextComponent>,
command: String, command: String,
) -> wasmtime::Result<()> { ) -> wasmtime::Result<Resource<TextComponent>> {
self.get_text_mut(&res)?.provider.0.style.click_event = Some(ClickEvent::RunCommand { self.get_text_mut(&res)?.provider.0.style.click_event = Some(ClickEvent::RunCommand {
command: Cow::Owned(command), command: Cow::Owned(command),
}); });
Ok(()) Ok(res)
} }
async fn click_suggest_command( async fn click_suggest_command(
&mut self, &mut self,
res: Resource<TextComponent>, res: Resource<TextComponent>,
command: String, command: String,
) -> wasmtime::Result<()> { ) -> wasmtime::Result<Resource<TextComponent>> {
self.get_text_mut(&res)?.provider.0.style.click_event = Some(ClickEvent::SuggestCommand { self.get_text_mut(&res)?.provider.0.style.click_event = Some(ClickEvent::SuggestCommand {
command: Cow::Owned(command), command: Cow::Owned(command),
}); });
Ok(()) Ok(res)
} }
async fn click_copy_to_clipboard( async fn click_copy_to_clipboard(
&mut self, &mut self,
res: Resource<TextComponent>, res: Resource<TextComponent>,
text: String, text: String,
) -> wasmtime::Result<()> { ) -> wasmtime::Result<Resource<TextComponent>> {
self.get_text_mut(&res)?.provider.0.style.click_event = Some(ClickEvent::CopyToClipboard { self.get_text_mut(&res)?.provider.0.style.click_event = Some(ClickEvent::CopyToClipboard {
value: Cow::Owned(text), value: Cow::Owned(text),
}); });
Ok(()) Ok(res)
} }
async fn hover_show_text( async fn hover_show_text(
&mut self, &mut self,
res: Resource<TextComponent>, res: Resource<TextComponent>,
text: Resource<TextComponent>, text: Resource<TextComponent>,
) -> wasmtime::Result<()> { ) -> wasmtime::Result<Resource<TextComponent>> {
let hover_tc = self.take_text(&text)?.provider; let hover_tc = self.take_text(&text)?.provider;
self.get_text_mut(&res)?.provider.0.style.hover_event = Some(HoverEvent::ShowText { self.get_text_mut(&res)?.provider.0.style.hover_event = Some(HoverEvent::ShowText {
value: vec![hover_tc.0], value: vec![hover_tc.0],
}); });
Ok(()) Ok(res)
} }
async fn hover_show_item( async fn hover_show_item(
&mut self, &mut self,
res: Resource<TextComponent>, res: Resource<TextComponent>,
item: String, item: String,
) -> wasmtime::Result<()> { ) -> wasmtime::Result<Resource<TextComponent>> {
self.get_text_mut(&res)?.provider.0.style.hover_event = Some(HoverEvent::ShowItem { self.get_text_mut(&res)?.provider.0.style.hover_event = Some(HoverEvent::ShowItem {
id: Cow::Owned(item), id: Cow::Owned(item),
count: None, count: None,
}); });
Ok(()) Ok(res)
} }
async fn hover_show_entity( async fn hover_show_entity(
@ -296,7 +307,7 @@ impl pumpkin::plugin::text::HostTextComponent for PluginHostState {
entity_type: String, entity_type: String,
id: String, id: String,
name: Option<Resource<TextComponent>>, name: Option<Resource<TextComponent>>,
) -> wasmtime::Result<()> { ) -> wasmtime::Result<Resource<TextComponent>> {
let name_val = match name { let name_val = match name {
Some(r) => Some(vec![self.take_text(&r)?.provider.0]), Some(r) => Some(vec![self.take_text(&r)?.provider.0]),
None => None, None => None,
@ -306,7 +317,7 @@ impl pumpkin::plugin::text::HostTextComponent for PluginHostState {
uuid: Cow::Owned(id), uuid: Cow::Owned(id),
name: name_val, name: name_val,
}); });
Ok(()) Ok(res)
} }
async fn drop(&mut self, rep: Resource<TextComponent>) -> wasmtime::Result<()> { async fn drop(&mut self, rep: Resource<TextComponent>) -> wasmtime::Result<()> {