From f77bd42948fa3fd3033fa09a8870e9e821df309c Mon Sep 17 00:00:00 2001 From: Doug Anderson444 Date: Mon, 24 Jun 2024 09:43:01 -0300 Subject: [PATCH] bump wurbo-rs to v0.4.1 syntax changes for minijinja 2.0 --- Cargo.lock | 101 +++------------ Cargo.toml | 2 +- crates/seed-keeper-events/Cargo.toml | 2 +- crates/seed-keeper-wit-ui/Cargo.toml | 2 +- crates/seed-keeper-wit-ui/src/bindings.rs | 116 +++++++++++++---- crates/seed-keeper-wit-ui/src/input.rs | 13 +- crates/seed-keeper-wit-ui/src/lib.rs | 20 ++- crates/seed-keeper-wit-ui/src/output.rs | 13 +- crates/seed-keeper-wit-ui/src/page.rs | 15 ++- crates/seed-keeper-wit-ui/wit/world.wit | 4 +- .../crates/aggregate-wit-ui/src/bindings.rs | 117 ++++++++++++++---- examples/crates/aggregate-wit-ui/src/lib.rs | 55 +++----- examples/crates/edwards-ui/src/input.rs | 10 +- examples/crates/edwards-ui/src/lib.rs | 20 ++- examples/crates/edwards-ui/src/output.rs | 44 +++---- examples/crates/edwards-ui/src/page.rs | 10 +- 16 files changed, 289 insertions(+), 255 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c96106b..9aebe57 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,12 +41,12 @@ dependencies = [ name = "aggregate-wit-ui" version = "0.1.0" dependencies = [ - "minijinja", + "minijinja 1.0.12", "thiserror", "wasmtime", "wasmtime-wasi", "wit-bindgen-rt", - "wurbo 0.3.2", + "wurbo", ] [[package]] @@ -695,7 +695,7 @@ name = "edwards-ui" version = "0.1.0" dependencies = [ "wit-bindgen-rt", - "wurbo 0.3.2", + "wurbo", ] [[package]] @@ -1204,6 +1204,18 @@ dependencies = [ "serde_json", ] +[[package]] +name = "minijinja" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e136ef580d7955019ab0a407b68d77c292a9976907e217900f3f76bc8f6dc1a4" +dependencies = [ + "memo-map", + "self_cell", + "serde", + "serde_json", +] + [[package]] name = "miniz_oxide" version = "0.7.2" @@ -1299,51 +1311,6 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" -[[package]] -name = "pest" -version = "2.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f8023d0fb78c8e03784ea1c7f3fa36e68a723138990b8d5a47d916b651e7a8" -dependencies = [ - "memchr", - "thiserror", - "ucd-trie", -] - -[[package]] -name = "pest_derive" -version = "2.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0d24f72393fd16ab6ac5738bc33cdb6a9aa73f8b902e8fe29cf4e67d7dd1026" -dependencies = [ - "pest", - "pest_generator", -] - -[[package]] -name = "pest_generator" -version = "2.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc17e2a6c7d0a492f0158d7a4bd66cc17280308bbaff78d5bef566dca35ab80" -dependencies = [ - "pest", - "pest_meta", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "pest_meta" -version = "2.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "934cd7631c050f4674352a6e835d5f6711ffbfb9345c2fc0107155ac495ae293" -dependencies = [ - "once_cell", - "pest", - "sha2", -] - [[package]] name = "pin-project-lite" version = "0.2.13" @@ -1566,7 +1533,7 @@ version = "0.1.0" dependencies = [ "serde", "serde_with", - "wurbo 0.2.0", + "wurbo", ] [[package]] @@ -1591,7 +1558,7 @@ dependencies = [ "serde", "serde_json", "wit-bindgen-rt", - "wurbo 0.2.0", + "wurbo", ] [[package]] @@ -1913,12 +1880,6 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" -[[package]] -name = "ucd-trie" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" - [[package]] name = "unicode-bidi" version = "0.3.15" @@ -2729,40 +2690,18 @@ dependencies = [ [[package]] name = "wurbo" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "373d302e1aecbfdba6ddfe1860d3385d34f181f854c4493725555d7a988a57f1" -dependencies = [ - "base64ct", - "convert_case", - "lazy_static", - "minijinja", - "nanoid", - "pest", - "pest_derive", - "serde", - "serde_json", - "thiserror", - "wit-parser", -] - -[[package]] -name = "wurbo" -version = "0.3.2" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "929c1a2b099cbbcf3e8df0051d339dd0df17a9983193337c9a1814303e327a1a" +checksum = "c6cf55abeaaef723ceccb7b13901f260aba62605784d32c545f0e87df8b7fbc7" dependencies = [ "base64ct", "convert_case", "lazy_static", - "minijinja", + "minijinja 2.0.2", "nanoid", - "pest", - "pest_derive", "serde", "serde_json", "thiserror", - "wit-parser", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 611dd8f..ba205c9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ description = "Tools for working with crypto seeds." seed-keeper-core = { path = "crates/seed-keeper-core" } seed-keeper-events = { path = "crates/seed-keeper-events" } wit-bindgen-rt = { version = "0.26.0", features = ["bitflags"] } -wurbo = "0.3.2" +wurbo = "0.4.1" [package] name = "seed-keeper" diff --git a/crates/seed-keeper-events/Cargo.toml b/crates/seed-keeper-events/Cargo.toml index 30c8658..5614089 100644 --- a/crates/seed-keeper-events/Cargo.toml +++ b/crates/seed-keeper-events/Cargo.toml @@ -7,6 +7,6 @@ edition = "2021" crate-type = ["lib"] [dependencies] -wurbo = "0.2.0" +wurbo = "0.4.1" serde = { version = "1.0", features = ["derive"] } serde_with = { version = "3.6.0", features = ["base64"] } diff --git a/crates/seed-keeper-wit-ui/Cargo.toml b/crates/seed-keeper-wit-ui/Cargo.toml index 0e086e8..954c6ab 100644 --- a/crates/seed-keeper-wit-ui/Cargo.toml +++ b/crates/seed-keeper-wit-ui/Cargo.toml @@ -8,7 +8,7 @@ crate-type = ["cdylib"] [dependencies] wit-bindgen-rt = { workspace = true, features = ["bitflags"] } -wurbo = "0.2.0" +wurbo = "0.4.1" base64ct = { version = "1.6.0", features = ["alloc"] } seed-keeper-events = { path = "../seed-keeper-events" } diff --git a/crates/seed-keeper-wit-ui/src/bindings.rs b/crates/seed-keeper-wit-ui/src/bindings.rs index e0fb5cf..7c2f7fd 100644 --- a/crates/seed-keeper-wit-ui/src/bindings.rs +++ b/crates/seed-keeper-wit-ui/src/bindings.rs @@ -594,32 +594,103 @@ pub mod exports { _ => _rt::invalid_enum_discriminant(), }); } + #[doc(hidden)] + #[allow(non_snake_case)] + pub unsafe fn _export_customize_cabi( + arg0: *mut u8, + arg1: usize, + ) -> *mut u8 { + #[cfg(target_arch = "wasm32")] + _rt::run_ctors_once(); + let base6 = arg0; + let len6 = arg1; + let mut result6 = _rt::Vec::with_capacity(len6); + for i in 0..len6 { + let base = base6.add(i * 16); + let e6 = { + let l0 = *base.add(0).cast::<*mut u8>(); + let l1 = *base.add(4).cast::(); + let len2 = l1; + let bytes2 = _rt::Vec::from_raw_parts(l0.cast(), len2, len2); + let l3 = *base.add(8).cast::<*mut u8>(); + let l4 = *base.add(12).cast::(); + let len5 = l4; + let bytes5 = _rt::Vec::from_raw_parts(l3.cast(), len5, len5); + + (_rt::string_lift(bytes2), _rt::string_lift(bytes5)) + }; + result6.push(e6); + } + _rt::cabi_dealloc(base6, len6 * 16, 4); + let result7 = T::customize(result6); + let ptr8 = _RET_AREA.0.as_mut_ptr().cast::(); + match result7 { + Ok(_) => { + *ptr8.add(0).cast::() = (0i32) as u8; + } + Err(e) => { + *ptr8.add(0).cast::() = (1i32) as u8; + let vec9 = (e.into_bytes()).into_boxed_slice(); + let ptr9 = vec9.as_ptr().cast::(); + let len9 = vec9.len(); + ::core::mem::forget(vec9); + *ptr8.add(8).cast::() = len9; + *ptr8.add(4).cast::<*mut u8>() = ptr9.cast_mut(); + } + }; + ptr8 + } + #[doc(hidden)] + #[allow(non_snake_case)] + pub unsafe fn __post_return_customize(arg0: *mut u8) { + let l0 = i32::from(*arg0.add(0).cast::()); + match l0 { + 0 => (), + _ => { + let l1 = *arg0.add(4).cast::<*mut u8>(); + let l2 = *arg0.add(8).cast::(); + _rt::cabi_dealloc(l1, l2, 1); + } + } + } pub trait Guest { /// renders the initial Web component with the given data /// and the target template to use as top level entry point fn render(ctx: Context) -> Result<_rt::String, _rt::String>; /// listen on all or given selectors fn activate(selectors: Option<_rt::Vec<_rt::String>>); + /// Optionally customize the configuration of the templates used to render the component + fn customize( + templates: _rt::Vec<(_rt::String, _rt::String)>, + ) -> Result<(), _rt::String>; } #[doc(hidden)] macro_rules! __export_seed_keeper_wit_ui_wurbo_out_0_1_0_cabi{ - ($ty:ident with_types_in $($path_to_types:tt)*) => (const _: () = { + ($ty:ident with_types_in $($path_to_types:tt)*) => (const _: () = { - #[export_name = "seed-keeper:wit-ui/wurbo-out@0.1.0#render"] - unsafe extern "C" fn export_render(arg0: i32,arg1: *mut u8,arg2: *mut u8,arg3: usize,arg4: i32,arg5: *mut u8,arg6: usize,arg7: i32,arg8: *mut u8,arg9: usize,arg10: i32,arg11: *mut u8,arg12: usize,) -> *mut u8 { - $($path_to_types)*::_export_render_cabi::<$ty>(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12) - } - #[export_name = "cabi_post_seed-keeper:wit-ui/wurbo-out@0.1.0#render"] - unsafe extern "C" fn _post_return_render(arg0: *mut u8,) { - $($path_to_types)*::__post_return_render::<$ty>(arg0) - } - #[export_name = "seed-keeper:wit-ui/wurbo-out@0.1.0#activate"] - unsafe extern "C" fn export_activate(arg0: i32,arg1: *mut u8,arg2: usize,) { - $($path_to_types)*::_export_activate_cabi::<$ty>(arg0, arg1, arg2) - } - };); - } + #[export_name = "seed-keeper:wit-ui/wurbo-out@0.1.0#render"] + unsafe extern "C" fn export_render(arg0: i32,arg1: *mut u8,arg2: *mut u8,arg3: usize,arg4: i32,arg5: *mut u8,arg6: usize,arg7: i32,arg8: *mut u8,arg9: usize,arg10: i32,arg11: *mut u8,arg12: usize,) -> *mut u8 { + $($path_to_types)*::_export_render_cabi::<$ty>(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12) + } + #[export_name = "cabi_post_seed-keeper:wit-ui/wurbo-out@0.1.0#render"] + unsafe extern "C" fn _post_return_render(arg0: *mut u8,) { + $($path_to_types)*::__post_return_render::<$ty>(arg0) + } + #[export_name = "seed-keeper:wit-ui/wurbo-out@0.1.0#activate"] + unsafe extern "C" fn export_activate(arg0: i32,arg1: *mut u8,arg2: usize,) { + $($path_to_types)*::_export_activate_cabi::<$ty>(arg0, arg1, arg2) + } + #[export_name = "seed-keeper:wit-ui/wurbo-out@0.1.0#customize"] + unsafe extern "C" fn export_customize(arg0: *mut u8,arg1: usize,) -> *mut u8 { + $($path_to_types)*::_export_customize_cabi::<$ty>(arg0, arg1) + } + #[export_name = "cabi_post_seed-keeper:wit-ui/wurbo-out@0.1.0#customize"] + unsafe extern "C" fn _post_return_customize(arg0: *mut u8,) { + $($path_to_types)*::__post_return_customize::<$ty>(arg0) + } + };); + } #[doc(hidden)] pub(crate) use __export_seed_keeper_wit_ui_wurbo_out_0_1_0_cabi; #[repr(align(4))] @@ -693,8 +764,8 @@ pub(crate) use __export_seedworld_impl as export; #[cfg(target_arch = "wasm32")] #[link_section = "component-type:wit-bindgen:0.25.0:seedworld:encoded world"] #[doc(hidden)] -pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 982] = *b"\ -\0asm\x0d\0\x01\0\0\x19\x16wit-component-encoding\x04\0\x07\xd6\x06\x01A\x02\x01\ +pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 1025] = *b"\ +\0asm\x0d\0\x01\0\0\x19\x16wit-component-encoding\x04\0\x07\x81\x07\x01A\x02\x01\ A\x0d\x01B\x04\x01p}\x01k\0\x01r\x03\x08username\0\x08password\0\x09encrypted\x01\ \x04\0\x0bcredentials\x03\0\x02\x03\x01\x1eseed-keeper:wallet/types@0.1.0\x05\0\x02\ \x03\0\0\x0bcredentials\x01B\x0a\x02\x03\x02\x01\x01\x04\0\x0bcredentials\x03\0\0\ @@ -710,12 +781,13 @@ nput\x0a\x04load\x06\x04\0\x07content\x03\0\x0b\x01q\x05\x0ball-content\x01\x0c\ \0\x02\x0elisten-details\x01B\x06\x02\x03\x02\x01\x04\x04\0\x0elisten-details\x03\ \0\0\x01@\x01\x07details\x01\x01\0\x04\0\x10addeventlistener\x01\x02\x01@\x01\x07\ messages\x01\0\x04\0\x04emit\x01\x03\x03\x01!seed-keeper:wit-ui/wurbo-in@0.1.0\x05\ -\x05\x02\x03\0\x02\x07context\x01B\x09\x02\x03\x02\x01\x06\x04\0\x07context\x03\0\ +\x05\x02\x03\0\x02\x07context\x01B\x0e\x02\x03\x02\x01\x06\x04\0\x07context\x03\0\ \0\x01j\x01s\x01s\x01@\x01\x03ctx\x01\0\x02\x04\0\x06render\x01\x03\x01ps\x01k\x04\ -\x01@\x01\x09selectors\x05\x01\0\x04\0\x08activate\x01\x06\x04\x01\"seed-keeper:\ -wit-ui/wurbo-out@0.1.0\x05\x07\x04\x01\"seed-keeper:wit-ui/seedworld@0.1.0\x04\0\ -\x0b\x0f\x01\0\x09seedworld\x03\0\0\0G\x09producers\x01\x0cprocessed-by\x02\x0dw\ -it-component\x070.208.1\x10wit-bindgen-rust\x060.25.0"; +\x01@\x01\x09selectors\x05\x01\0\x04\0\x08activate\x01\x06\x01o\x02ss\x01p\x07\x01\ +j\0\x01s\x01@\x01\x09templates\x08\0\x09\x04\0\x09customize\x01\x0a\x04\x01\"see\ +d-keeper:wit-ui/wurbo-out@0.1.0\x05\x07\x04\x01\"seed-keeper:wit-ui/seedworld@0.\ +1.0\x04\0\x0b\x0f\x01\0\x09seedworld\x03\0\0\0G\x09producers\x01\x0cprocessed-by\ +\x02\x0dwit-component\x070.208.1\x10wit-bindgen-rust\x060.25.0"; #[inline(never)] #[doc(hidden)] diff --git a/crates/seed-keeper-wit-ui/src/input.rs b/crates/seed-keeper-wit-ui/src/input.rs index 3177eb6..7876efd 100644 --- a/crates/seed-keeper-wit-ui/src/input.rs +++ b/crates/seed-keeper-wit-ui/src/input.rs @@ -4,17 +4,18 @@ use super::*; #[derive(Debug, Clone, Default)] pub(crate) struct Input(Option); -impl StructObject for Input { - fn get_field(&self, name: &str) -> Option { - match name { +impl Object for Input { + fn get_value(self: &std::sync::Arc, key: &Value) -> Option { + match key.as_str()? { "id" => Some(Value::from(rand_id())), "placeholder" => Some(Value::from( self.as_ref() + .as_ref() .map(|c| c.placeholder.clone()) .unwrap_or_default(), )), // copy encrypted_seed from Input, if any - "encrypted_seed" => match self.as_ref() { + "encrypted_seed" => match self.as_ref().as_ref() { Some(val) => match &val.encrypted_seed { Some(encrypted) => Some(Value::from(encrypted.clone())), None => None, @@ -24,10 +25,6 @@ impl StructObject for Input { _ => None, } } - /// So that debug will show the values - fn static_fields(&self) -> Option<&'static [&'static str]> { - Some(&["id", "placeholder"]) - } } impl From for Input { diff --git a/crates/seed-keeper-wit-ui/src/lib.rs b/crates/seed-keeper-wit-ui/src/lib.rs index 92ae8ce..61c07e2 100644 --- a/crates/seed-keeper-wit-ui/src/lib.rs +++ b/crates/seed-keeper-wit-ui/src/lib.rs @@ -47,7 +47,7 @@ fn get_templates() -> Templates { // Macro builds the Component struct and implements the Guest trait for us, saving copy-and-paste prelude_bindgen! {WurboGuest, Component, StructContext, Context, LAST_STATE} -/// PageContext is a struct of other structs that implement [StructObject], +/// PageContext is a struct of other structs that implement [Object], /// which is why it is not a Newtype wrapper like the others are. #[derive(Debug, Clone, Default)] pub struct StructContext { @@ -65,19 +65,15 @@ impl StructContext { } } -impl StructObject for StructContext { - fn get_field(&self, name: &str) -> Option { - match name { - "page" => Some(Value::from_struct_object(self.page.clone())), - "input" => Some(Value::from_struct_object(self.input.clone())), - "output" => Some(Value::from_struct_object(self.output.clone())), +impl Object for StructContext { + fn get_value(self: &std::sync::Arc, key: &Value) -> Option { + match key.as_str()? { + "page" => Some(Value::from_object(self.page.clone())), + "input" => Some(Value::from_object(self.input.clone())), + "output" => Some(Value::from_object(self.output.clone())), _ => None, } } - /// So that debug will show the values - fn static_fields(&self) -> Option<&'static [&'static str]> { - Some(&["page", "input", "output"]) - } } /// We received Context from the WIT ABI and need to convert it to PageContext @@ -112,7 +108,7 @@ impl From for StructContext { StructContext { page: Page::from(context.page), input: Input::from(context.input), - // We can use default for Output because the minijinja StructObject impl will + // We can use default for Output because the minijinja Object impl will // calculate the values from the above inouts for us output: Output::default(), target: None, diff --git a/crates/seed-keeper-wit-ui/src/output.rs b/crates/seed-keeper-wit-ui/src/output.rs index 3f24723..28396cf 100644 --- a/crates/seed-keeper-wit-ui/src/output.rs +++ b/crates/seed-keeper-wit-ui/src/output.rs @@ -80,11 +80,11 @@ impl From for Credentials { } } -/// Implement StructObject for Output so we can use minijina to automagically calculate the length +/// Implement [Object] for Output so we can use minijina to automagically calculate the length /// of the username and password concatenated -impl StructObject for Output { - fn get_field(&self, name: &str) -> Option { - match name { +impl Object for Output { + fn get_value(self: &std::sync::Arc, key: &Value) -> Option { + match key.as_str()? { // if self.id.is_some, use it, otherwise generate a new one "id" => Some(Value::from(OUTPUT_ID.get_or_init(|| rand_id()).to_owned())), "username" => Some(Value::from(self.username.clone())), @@ -101,11 +101,6 @@ impl StructObject for Output { _ => None, } } - - /// So that debug will show the values - fn static_fields(&self) -> Option<&'static [&'static str]> { - Some(&["id", "username", "password", "seed"]) - } } /// [Encrypted] is the encrypted seed passed from the User, if any. diff --git a/crates/seed-keeper-wit-ui/src/page.rs b/crates/seed-keeper-wit-ui/src/page.rs index ad89e66..4fdd0ae 100644 --- a/crates/seed-keeper-wit-ui/src/page.rs +++ b/crates/seed-keeper-wit-ui/src/page.rs @@ -6,20 +6,19 @@ static PAGE_ID: OnceLock = OnceLock::new(); #[derive(Debug, Clone, Default)] pub(crate) struct Page(Option); -impl StructObject for Page { - fn get_field(&self, name: &str) -> Option { - match name { +impl Object for Page { + fn get_value(self: &std::sync::Arc, key: &Value) -> Option { + match key.as_str()? { "title" => Some(Value::from( - self.as_ref().map(|v| v.title.clone()).unwrap_or_default(), + self.as_ref() + .as_ref() + .map(|v| v.title.clone()) + .unwrap_or_default(), )), "id" => Some(Value::from(PAGE_ID.get_or_init(|| rand_id()).to_owned())), _ => None, } } - /// So that debug will show the values - fn static_fields(&self) -> Option<&'static [&'static str]> { - Some(&["title", "id"]) - } } impl From for Page { diff --git a/crates/seed-keeper-wit-ui/wit/world.wit b/crates/seed-keeper-wit-ui/wit/world.wit index b1b2c74..e84d8f1 100644 --- a/crates/seed-keeper-wit-ui/wit/world.wit +++ b/crates/seed-keeper-wit-ui/wit/world.wit @@ -46,7 +46,6 @@ interface wurbo-in { // Emit events from this component. Messages should be serialized JSON strings of Event type. emit: func(message: string); - } interface wurbo-out { @@ -59,6 +58,9 @@ interface wurbo-out { // listen on all or given selectors activate: func(selectors: option>); + + // Optionally customize the configuration of the templates used to render the component + customize: func(templates: list>) -> result<_, string>; } /// An example world for the component to target. diff --git a/examples/crates/aggregate-wit-ui/src/bindings.rs b/examples/crates/aggregate-wit-ui/src/bindings.rs index a355c88..acf4c3b 100644 --- a/examples/crates/aggregate-wit-ui/src/bindings.rs +++ b/examples/crates/aggregate-wit-ui/src/bindings.rs @@ -831,6 +831,80 @@ pub mod seed_keeper { } } } + #[allow(unused_unsafe, clippy::all)] + /// Optionally customize the configuration of the templates used to render the component + pub fn customize(templates: &[(_rt::String, _rt::String)]) -> Result<(), _rt::String> { + unsafe { + #[repr(align(4))] + struct RetArea([::core::mem::MaybeUninit; 12]); + let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 12]); + let vec3 = templates; + let len3 = vec3.len(); + let layout3 = _rt::alloc::Layout::from_size_align_unchecked(vec3.len() * 16, 4); + let result3 = if layout3.size() != 0 { + let ptr = _rt::alloc::alloc(layout3).cast::(); + if ptr.is_null() { + _rt::alloc::handle_alloc_error(layout3); + } + ptr + } else { + { + ::core::ptr::null_mut() + } + }; + for (i, e) in vec3.into_iter().enumerate() { + let base = result3.add(i * 16); + { + let (t0_0, t0_1) = e; + let vec1 = t0_0; + let ptr1 = vec1.as_ptr().cast::(); + let len1 = vec1.len(); + *base.add(4).cast::() = len1; + *base.add(0).cast::<*mut u8>() = ptr1.cast_mut(); + let vec2 = t0_1; + let ptr2 = vec2.as_ptr().cast::(); + let len2 = vec2.len(); + *base.add(12).cast::() = len2; + *base.add(8).cast::<*mut u8>() = ptr2.cast_mut(); + } + } + let ptr4 = ret_area.0.as_mut_ptr().cast::(); + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "seed-keeper:wit-ui/wurbo-out@0.1.0")] + extern "C" { + #[link_name = "customize"] + fn wit_import(_: *mut u8, _: usize, _: *mut u8); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: *mut u8, _: usize, _: *mut u8) { + unreachable!() + } + wit_import(result3, len3, ptr4); + let l5 = i32::from(*ptr4.add(0).cast::()); + if layout3.size() != 0 { + _rt::alloc::dealloc(result3.cast(), layout3); + } + match l5 { + 0 => { + let e = (); + Ok(e) + } + 1 => { + let e = { + let l6 = *ptr4.add(4).cast::<*mut u8>(); + let l7 = *ptr4.add(8).cast::(); + let len8 = l7; + let bytes8 = _rt::Vec::from_raw_parts(l6.cast(), len8, len8); + + _rt::string_lift(bytes8) + }; + Err(e) + } + _ => _rt::invalid_enum_discriminant(), + } + } + } } } } @@ -1759,8 +1833,8 @@ pub(crate) use __export_agg_impl as export; #[cfg(target_arch = "wasm32")] #[link_section = "component-type:wit-bindgen:0.25.0:agg:encoded world"] #[doc(hidden)] -pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 1647] = *b"\ -\0asm\x0d\0\x01\0\0\x19\x16wit-component-encoding\x04\0\x07\xf5\x0b\x01A\x02\x01\ +pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 1690] = *b"\ +\0asm\x0d\0\x01\0\0\x19\x16wit-component-encoding\x04\0\x07\xa0\x0c\x01A\x02\x01\ A\x16\x01B\x0e\x01r\x02\x08selectors\x02tys\x04\0\x0elisten-details\x03\0\0\x01r\ \x01\x05titles\x04\0\x04page\x03\0\x02\x01r\x01\x0bplaceholders\x04\0\x05input\x03\ \0\x04\x01ks\x01r\x04\x05value\x06\x02id\x06\x07message\x06\x09signature\x06\x04\ @@ -1778,26 +1852,27 @@ tles\x04\0\x04page\x03\0\x04\x01ks\x01r\x02\x0bplaceholders\x0eencrypted-seed\x0 load\x06\x04\0\x07content\x03\0\x0b\x01q\x05\x0ball-content\x01\x0c\0\x08usernam\ e\x01s\0\x08password\x01s\0\x09encrypted\x01\x01\0\x06submit\0\0\x04\0\x07contex\ t\x03\0\x0d\x03\x01$seed-keeper:wit-ui/wurbo-types@0.1.0\x05\x03\x02\x03\0\x02\x07\ -context\x01B\x09\x02\x03\x02\x01\x04\x04\0\x07context\x03\0\0\x01j\x01s\x01s\x01\ +context\x01B\x0e\x02\x03\x02\x01\x04\x04\0\x07context\x03\0\0\x01j\x01s\x01s\x01\ @\x01\x03ctx\x01\0\x02\x04\0\x06render\x01\x03\x01ps\x01k\x04\x01@\x01\x09select\ -ors\x05\x01\0\x04\0\x08activate\x01\x06\x03\x01\"seed-keeper:wit-ui/wurbo-out@0.\ -1.0\x05\x05\x02\x03\0\x01\x07context\x02\x03\0\x03\x07context\x01B\x0c\x02\x03\x02\ -\x01\x06\x04\0\x0fedwards-context\x03\0\0\x02\x03\x02\x01\x07\x04\0\x0cseed-cont\ -ext\x03\0\x02\x01r\x02\x08selectors\x02tys\x04\0\x0elisten-details\x03\0\x04\x01\ -r\x01\x05titles\x04\0\x03app\x03\0\x06\x01r\x03\x03app\x07\x07seed-ui\x03\x0aedw\ -ards-ui\x01\x04\0\x07content\x03\0\x08\x01q\x03\x0ball-content\x01\x09\0\x04seed\ -\x01\x03\0\x07edwards\x01\x01\0\x04\0\x07context\x03\0\x0a\x03\x01)wallet:aggreg\ -ate-wit-ui/wurbo-types@0.1.0\x05\x08\x02\x03\0\x04\x0elisten-details\x01B\x04\x02\ -\x03\x02\x01\x09\x04\0\x0elisten-details\x03\0\0\x01@\x01\x07details\x01\x01\0\x04\ -\0\x10addeventlistener\x01\x02\x03\x01&wallet:aggregate-wit-ui/wurbo-in@0.1.0\x05\ -\x0a\x02\x03\0\x04\x07context\x01B\x09\x02\x03\x02\x01\x0b\x04\0\x07context\x03\0\ -\0\x01j\x01s\x01s\x01@\x01\x03ctx\x01\0\x02\x04\0\x06render\x01\x03\x01ps\x01k\x04\ -\x01@\x01\x09selectors\x05\x01\0\x04\0\x08activate\x01\x06\x04\x01'wallet:aggreg\ -ate-wit-ui/wurbo-out@0.1.0\x05\x0c\x01B\x04\x01ps\x01k\0\x01@\x01\x09selectors\x01\ -\x01\0\x04\0\x09activates\x01\x02\x04\x01)wallet:aggregate-wit-ui/aggregation@0.\ -1.0\x05\x0d\x04\x01!wallet:aggregate-wit-ui/agg@0.1.0\x04\0\x0b\x09\x01\0\x03agg\ -\x03\0\0\0G\x09producers\x01\x0cprocessed-by\x02\x0dwit-component\x070.208.1\x10\ -wit-bindgen-rust\x060.25.0"; +ors\x05\x01\0\x04\0\x08activate\x01\x06\x01o\x02ss\x01p\x07\x01j\0\x01s\x01@\x01\ +\x09templates\x08\0\x09\x04\0\x09customize\x01\x0a\x03\x01\"seed-keeper:wit-ui/w\ +urbo-out@0.1.0\x05\x05\x02\x03\0\x01\x07context\x02\x03\0\x03\x07context\x01B\x0c\ +\x02\x03\x02\x01\x06\x04\0\x0fedwards-context\x03\0\0\x02\x03\x02\x01\x07\x04\0\x0c\ +seed-context\x03\0\x02\x01r\x02\x08selectors\x02tys\x04\0\x0elisten-details\x03\0\ +\x04\x01r\x01\x05titles\x04\0\x03app\x03\0\x06\x01r\x03\x03app\x07\x07seed-ui\x03\ +\x0aedwards-ui\x01\x04\0\x07content\x03\0\x08\x01q\x03\x0ball-content\x01\x09\0\x04\ +seed\x01\x03\0\x07edwards\x01\x01\0\x04\0\x07context\x03\0\x0a\x03\x01)wallet:ag\ +gregate-wit-ui/wurbo-types@0.1.0\x05\x08\x02\x03\0\x04\x0elisten-details\x01B\x04\ +\x02\x03\x02\x01\x09\x04\0\x0elisten-details\x03\0\0\x01@\x01\x07details\x01\x01\ +\0\x04\0\x10addeventlistener\x01\x02\x03\x01&wallet:aggregate-wit-ui/wurbo-in@0.\ +1.0\x05\x0a\x02\x03\0\x04\x07context\x01B\x09\x02\x03\x02\x01\x0b\x04\0\x07conte\ +xt\x03\0\0\x01j\x01s\x01s\x01@\x01\x03ctx\x01\0\x02\x04\0\x06render\x01\x03\x01p\ +s\x01k\x04\x01@\x01\x09selectors\x05\x01\0\x04\0\x08activate\x01\x06\x04\x01'wal\ +let:aggregate-wit-ui/wurbo-out@0.1.0\x05\x0c\x01B\x04\x01ps\x01k\0\x01@\x01\x09s\ +electors\x01\x01\0\x04\0\x09activates\x01\x02\x04\x01)wallet:aggregate-wit-ui/ag\ +gregation@0.1.0\x05\x0d\x04\x01!wallet:aggregate-wit-ui/agg@0.1.0\x04\0\x0b\x09\x01\ +\0\x03agg\x03\0\0\0G\x09producers\x01\x0cprocessed-by\x02\x0dwit-component\x070.\ +208.1\x10wit-bindgen-rust\x060.25.0"; #[inline(never)] #[doc(hidden)] diff --git a/examples/crates/aggregate-wit-ui/src/lib.rs b/examples/crates/aggregate-wit-ui/src/lib.rs index 4f5a938..aeb6cd4 100644 --- a/examples/crates/aggregate-wit-ui/src/lib.rs +++ b/examples/crates/aggregate-wit-ui/src/lib.rs @@ -58,7 +58,7 @@ impl WurboGuest for Component { .expect("template should be added"); } - let struct_ctx = Value::from_struct_object(AppContext::from(ctx.clone())); + let struct_ctx = Value::from_object(AppContext::from(ctx.clone())); let prnt_err = |e| { println!("Could not render template: {:#}", e); @@ -101,19 +101,15 @@ pub(crate) struct AppContext { edwards_ui: Edwards, } -impl StructObject for AppContext { - fn get_field(&self, name: &str) -> Option { - match name { - "app" => Some(Value::from_struct_object(self.app.clone())), - "seed_ui" => Some(Value::from_struct_object(self.seed_ui.clone())), - "edwards_ui" => Some(Value::from_struct_object(self.edwards_ui.clone())), +impl Object for AppContext { + fn get_value(self: &std::sync::Arc, key: &Value) -> Option { + match key.as_str()? { + "app" => Some(Value::from_object(self.app.clone())), + "seed_ui" => Some(Value::from_object(self.seed_ui.clone())), + "edwards_ui" => Some(Value::from_object(self.edwards_ui.clone())), _ => None, } } - /// So that debug will show the values - fn static_fields(&self) -> Option<&'static [&'static str]> { - Some(&["app", "seed_ui", "edwards_ui"]) - } } /// We have all the content, convert it to AppContext @@ -133,18 +129,14 @@ impl From for AppContext { #[derive(Debug, Clone)] pub(crate) struct App(wurbo_types::App); -impl StructObject for App { - fn get_field(&self, name: &str) -> Option { - match name { +impl Object for App { + fn get_value(self: &std::sync::Arc, key: &Value) -> Option { + match key.as_str()? { "title" => Some(Value::from(self.title.clone())), "id" => Some(Value::from(rand_id())), _ => None, } } - /// So that debug will show the values - fn static_fields(&self) -> Option<&'static [&'static str]> { - Some(&["title", "id"]) - } } impl From for App { @@ -161,28 +153,23 @@ impl Deref for App { } } -/// Wrapper around the seed keeper context so we can implement StructObject on top of it +/// Wrapper around the seed keeper context so we can implement [Object] on top of it #[derive(Debug, Clone)] struct SeedUI(wurbo_types::SeedContext); -/// Implement StructObject for SeedKeeper so that we can use it in the template +/// Implement [Object] for SeedKeeper so that we can use it in the template /// The main point of this impl is to call render(ctx) on the SeedKeeperUIContext /// and return the HTML string as the Value -impl StructObject for SeedUI { +impl Object for SeedUI { /// Simply passes through the seed context to the component for rendering /// outputs to .html - fn get_field(&self, name: &str) -> Option { + fn get_value(self: &std::sync::Arc, key: &Value) -> Option { let render_result = wit_ui::wurbo_out::render(&self); - match (name, render_result) { + match (key.as_str()?, render_result) { ("html", Ok(html)) => Some(Value::from(html)), _ => None, } } - - /// So that debug will show the values - fn static_fields(&self) -> Option<&'static [&'static str]> { - Some(&["html"]) - } } impl From for SeedUI { @@ -202,21 +189,17 @@ impl Deref for SeedUI { #[derive(Debug, Clone)] struct Edwards(wurbo_types::EdwardsContext); -/// Implement StructObject for Edwards so that we can use it in the template +/// Implement [Object] for Edwards so that we can use it in the template /// The main point of this impl is to call render(ctx) on the EdwardsUIContext /// and return the HTML string as the Value -impl StructObject for Edwards { - fn get_field(&self, name: &str) -> Option { +impl Object for Edwards { + fn get_value(self: &std::sync::Arc, key: &Value) -> Option { let render_result = edwards_ui::wurbo_out::render(&self); - match (name, render_result) { + match (key.as_str()?, render_result) { ("html", Ok(html)) => Some(Value::from(html)), _ => None, } } - /// So that debug will show the values - fn static_fields(&self) -> Option<&'static [&'static str]> { - Some(&["html"]) - } } impl From for Edwards { diff --git a/examples/crates/edwards-ui/src/input.rs b/examples/crates/edwards-ui/src/input.rs index 8f3650a..2864569 100644 --- a/examples/crates/edwards-ui/src/input.rs +++ b/examples/crates/edwards-ui/src/input.rs @@ -4,19 +4,15 @@ use super::*; #[derive(Debug, Clone)] pub(crate) struct Input(wurbo_types::Input); -impl StructObject for Input { - fn get_field(&self, name: &str) -> Option { - match name { +impl Object for Input { + fn get_value(self: &std::sync::Arc, key: &Value) -> Option { + match key.as_str()? { "placeholder" => Some(Value::from(self.placeholder.clone())), "message_input" => Some(Value::from(rand_id())), "submit_button" => Some(Value::from(rand_id())), _ => None, } } - /// So that debug will show the values - fn static_fields(&self) -> Option<&'static [&'static str]> { - Some(&["placeholder", "message_input", "submit_button"]) - } } impl From for Input { diff --git a/examples/crates/edwards-ui/src/lib.rs b/examples/crates/edwards-ui/src/lib.rs index 32dcbcb..bcc55ae 100644 --- a/examples/crates/edwards-ui/src/lib.rs +++ b/examples/crates/edwards-ui/src/lib.rs @@ -39,7 +39,7 @@ fn get_templates() -> Templates { // Macro builds the Component struct and implements the Guest trait for us, saving copy-and-paste prelude_bindgen! {WurboGuest, Component, PageContext, Context, LAST_STATE} -/// PageContext is a struct of other structs that implement [StructObject], +/// PageContext is a struct of other structs that implement [Object], /// which is why it is not a Newtype wrapper like the others are. #[derive(Debug, Clone)] pub struct PageContext { @@ -49,19 +49,15 @@ pub struct PageContext { target: Option, } -impl StructObject for PageContext { - fn get_field(&self, name: &str) -> Option { - match name { - "page" => Some(Value::from_struct_object(self.page.clone())), - "input" => Some(Value::from_struct_object(self.input.clone())), - "output" => Some(Value::from_struct_object(self.output.clone())), +impl Object for PageContext { + fn get_value(self: &std::sync::Arc, key: &Value) -> Option { + match key.as_str()? { + "page" => Some(Value::from_object(self.page.clone())), + "input" => Some(Value::from_object(self.input.clone())), + "output" => Some(Value::from_object(self.output.clone())), _ => None, } } - /// So that debug will show the values - fn static_fields(&self) -> Option<&'static [&'static str]> { - Some(&["page", "input", "output"]) - } } /// We received Context from the WIT ABO and need to convert it to PageContext @@ -83,7 +79,7 @@ impl From for PageContext { PageContext { page: Page::from(context.page), input: Input::from(context.input), - // We can use default for Output because the minijinja StructObject impl will + // We can use default for Output because the minijinja Object impl will // calculate the values from the above inouts for us output: Output::default(), target: None, diff --git a/examples/crates/edwards-ui/src/output.rs b/examples/crates/edwards-ui/src/output.rs index f306801..eee5595 100644 --- a/examples/crates/edwards-ui/src/output.rs +++ b/examples/crates/edwards-ui/src/output.rs @@ -10,45 +10,38 @@ pub(super) struct Output { pub(crate) log: String, } -/// Impleent StructObject for Output so we can use minijina to automagically calculate the length +/// Impl [Object] for Output so we can use minijina to automagically calculate the length /// of the message and button concatenated -impl StructObject for Output { - fn get_field(&self, name: &str) -> Option { - match name { - "message" => Some(Value::from_struct_object(self.message.clone())), - "signature" => Some(Value::from_struct_object(self.signature.clone())), +impl Object for Output { + fn get_value(self: &std::sync::Arc, key: &Value) -> Option { + match key.as_str()? { + "message" => Some(Value::from_object(self.message.clone())), + "signature" => Some(Value::from_object(self.signature.clone())), "log" => Some(Value::from(self.log.clone())), // if self.id.is_some, use it, otherwise generate a new one "id" => Some(Value::from(OUTPUT_ID.get_or_init(|| rand_id()).to_owned())), _ => None, } } - - /// So that debug will show the values - fn static_fields(&self) -> Option<&'static [&'static str]> { - Some(&["id", "message", "signature", "log"]) - } } /// Message captures is the message input value. #[derive(Debug, Default, Clone)] pub(crate) struct Message(Option); -impl StructObject for Message { - fn get_field(&self, name: &str) -> Option { - match name { +impl Object for Message { + fn get_value(self: &std::sync::Arc, key: &Value) -> Option { + match key.as_str()? { "value" => Some(Value::from( // Deref self and use value if is_Some, otherwise use "" - self.as_ref().map(|v| v.clone()).unwrap_or_default(), + self.as_ref() + .as_ref() + .map(|v| v.clone()) + .unwrap_or_default(), )), _ => None, } } - - /// So that debug will show the values - fn static_fields(&self) -> Option<&'static [&'static str]> { - Some(&["value"]) - } } impl From<&String> for Message { @@ -94,9 +87,9 @@ impl Signature { } } -impl StructObject for Signature { - fn get_field(&self, name: &str) -> Option { - match name { +impl Object for Signature { + fn get_value(self: &std::sync::Arc, key: &Value) -> Option { + match key.as_str()? { "value" => Some(Value::from(self.0.clone())), "hex" => { let literal = format!("{:X?}", self.0.clone()); @@ -107,11 +100,6 @@ impl StructObject for Signature { _ => None, } } - - /// So that debug will show the values - fn static_fields(&self) -> Option<&'static [&'static str]> { - Some(&["value"]) - } } impl Deref for Signature { diff --git a/examples/crates/edwards-ui/src/page.rs b/examples/crates/edwards-ui/src/page.rs index 8fade78..2e95efd 100644 --- a/examples/crates/edwards-ui/src/page.rs +++ b/examples/crates/edwards-ui/src/page.rs @@ -4,18 +4,14 @@ use super::*; #[derive(Debug, Clone)] pub(crate) struct Page(wurbo_types::Page); -impl StructObject for Page { - fn get_field(&self, name: &str) -> Option { - match name { +impl Object for Page { + fn get_value(self: &std::sync::Arc, key: &Value) -> Option { + match key.as_str()? { "title" => Some(Value::from(self.title.clone())), "id" => Some(Value::from(rand_id())), _ => None, } } - /// So that debug will show the values - fn static_fields(&self) -> Option<&'static [&'static str]> { - Some(&["title", "id"]) - } } impl From for Page {