-
Notifications
You must be signed in to change notification settings - Fork 6
Update order quote wasm bindings to use wasm export macro #1706
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
e291734
1b1bb66
a480584
3fad091
1d963f8
4a0b6c2
fb5809d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,162 +1,238 @@ | ||||||||||||||||||||||||
use crate::{error::Error, BatchQuoteSpec, QuoteSpec}; | ||||||||||||||||||||||||
use crate::{get_order_quotes, BatchQuoteTarget, QuoteTarget}; | ||||||||||||||||||||||||
use crate::{ | ||||||||||||||||||||||||
get_order_quotes, BatchOrderQuotesResponse, BatchQuoteTarget, OrderQuoteValue, QuoteTarget, | ||||||||||||||||||||||||
}; | ||||||||||||||||||||||||
use alloy::hex::FromHexError; | ||||||||||||||||||||||||
use alloy::primitives::ruint::ParseError; | ||||||||||||||||||||||||
use alloy::primitives::{ | ||||||||||||||||||||||||
hex::{encode_prefixed, FromHex}, | ||||||||||||||||||||||||
Address, U256, | ||||||||||||||||||||||||
}; | ||||||||||||||||||||||||
use rain_orderbook_bindings::wasm_traits::TryIntoU256; | ||||||||||||||||||||||||
use rain_orderbook_subgraph_client::{types::common::SgOrder, utils::make_order_id}; | ||||||||||||||||||||||||
use serde::{Deserialize, Serialize}; | ||||||||||||||||||||||||
use std::str::FromStr; | ||||||||||||||||||||||||
use wasm_bindgen_utils::prelude::*; | ||||||||||||||||||||||||
use thiserror::Error; | ||||||||||||||||||||||||
use wasm_bindgen_utils::{impl_wasm_traits, prelude::*, wasm_export}; | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
#[derive(Serialize, Deserialize, Debug, Clone, Tsify)] | ||||||||||||||||||||||||
#[serde(untagged)] | ||||||||||||||||||||||||
pub enum QuoteResultEnum { | ||||||||||||||||||||||||
Success { | ||||||||||||||||||||||||
value: OrderQuoteValue, | ||||||||||||||||||||||||
#[tsify(type = "undefined")] | ||||||||||||||||||||||||
error: Option<String>, | ||||||||||||||||||||||||
}, | ||||||||||||||||||||||||
Err { | ||||||||||||||||||||||||
#[tsify(type = "undefined")] | ||||||||||||||||||||||||
value: Option<OrderQuoteValue>, | ||||||||||||||||||||||||
error: String, | ||||||||||||||||||||||||
}, | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
impl_wasm_traits!(QuoteResultEnum); | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
#[derive(Serialize, Deserialize, Debug, Clone, Tsify)] | ||||||||||||||||||||||||
#[serde(rename_all = "camelCase")] | ||||||||||||||||||||||||
pub struct DoQuoteTargetsResult(pub Vec<QuoteResultEnum>); | ||||||||||||||||||||||||
impl_wasm_traits!(DoQuoteTargetsResult); | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
#[derive(Serialize, Deserialize, Debug, Clone, Tsify)] | ||||||||||||||||||||||||
#[serde(rename_all = "camelCase")] | ||||||||||||||||||||||||
pub struct DoQuoteSpecsResult(pub Vec<QuoteResultEnum>); | ||||||||||||||||||||||||
impl_wasm_traits!(DoQuoteSpecsResult); | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
#[derive(Serialize, Deserialize, Debug, Clone, Tsify)] | ||||||||||||||||||||||||
#[serde(rename_all = "camelCase")] | ||||||||||||||||||||||||
pub struct QuoteTargetResult( | ||||||||||||||||||||||||
#[tsify(type = "(QuoteTarget | undefined)[]")] pub Vec<Option<QuoteTarget>>, | ||||||||||||||||||||||||
); | ||||||||||||||||||||||||
impl_wasm_traits!(QuoteTargetResult); | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
#[derive(Serialize, Deserialize, Debug, Clone, Tsify)] | ||||||||||||||||||||||||
#[serde(rename_all = "camelCase")] | ||||||||||||||||||||||||
pub struct DoOrderQuoteResult(pub Vec<BatchOrderQuotesResponse>); | ||||||||||||||||||||||||
impl_wasm_traits!(DoOrderQuoteResult); | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
/// Get subgraph represented "order_id" of a QuoteTarget | ||||||||||||||||||||||||
#[wasm_bindgen(js_name = "getId")] | ||||||||||||||||||||||||
pub fn get_id(orderbook: &str, order_hash: &str) -> String { | ||||||||||||||||||||||||
let mut orderbook_error = "orderbook address, ".to_string(); | ||||||||||||||||||||||||
let mut order_hash_error = "order hash, ".to_string(); | ||||||||||||||||||||||||
let orderbook = Address::from_hex(orderbook) | ||||||||||||||||||||||||
.inspect_err(|e| orderbook_error.push_str(&e.to_string())) | ||||||||||||||||||||||||
.expect_throw(&orderbook_error); | ||||||||||||||||||||||||
let order_hash = U256::from_str(order_hash) | ||||||||||||||||||||||||
.inspect_err(|e| order_hash_error.push_str(&e.to_string())) | ||||||||||||||||||||||||
.expect_throw(&order_hash_error); | ||||||||||||||||||||||||
encode_prefixed(make_order_id(orderbook, order_hash)) | ||||||||||||||||||||||||
#[wasm_export(js_name = "getId", unchecked_return_type = "string")] | ||||||||||||||||||||||||
pub fn get_id(orderbook: &str, order_hash: &str) -> Result<String, QuoteBindingsError> { | ||||||||||||||||||||||||
let orderbook = Address::from_hex(orderbook)?; | ||||||||||||||||||||||||
let order_hash = U256::from_str(order_hash)?; | ||||||||||||||||||||||||
Ok(encode_prefixed(make_order_id(orderbook, order_hash))) | ||||||||||||||||||||||||
Comment on lines
+57
to
+61
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
- let order_hash = U256::from_str(order_hash)?;
+ let order_hash = U256::from_hex(order_hash)?; This keeps the function symmetrical with the 📝 Committable suggestion
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We don't need to do this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @findolor Understood, I'll respect your decision not to make this change. Thanks for the clarification. ✏️ Learnings added
|
||||||||||||||||||||||||
} | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
/// Quotes the target on the given rpc url | ||||||||||||||||||||||||
/// Resolves with array of OrderQuoteValue object or a string error | ||||||||||||||||||||||||
#[wasm_bindgen(js_name = "doQuoteTargets")] | ||||||||||||||||||||||||
#[wasm_export( | ||||||||||||||||||||||||
js_name = "doQuoteTargets", | ||||||||||||||||||||||||
unchecked_return_type = "DoQuoteTargetsResult" | ||||||||||||||||||||||||
)] | ||||||||||||||||||||||||
pub async fn do_quote_targets( | ||||||||||||||||||||||||
quote_targets: &BatchQuoteTarget, | ||||||||||||||||||||||||
rpc_url: &str, | ||||||||||||||||||||||||
block_number: Option<u64>, | ||||||||||||||||||||||||
gas: Option<js_sys::BigInt>, | ||||||||||||||||||||||||
multicall_address: Option<String>, | ||||||||||||||||||||||||
) -> Result<JsValue, Error> { | ||||||||||||||||||||||||
let mut multicall_address_error = "multicall address, ".to_string(); | ||||||||||||||||||||||||
let multicall_address = multicall_address.map(|v| { | ||||||||||||||||||||||||
Address::from_hex(v) | ||||||||||||||||||||||||
.inspect_err(|e| multicall_address_error.push_str(&e.to_string())) | ||||||||||||||||||||||||
.expect_throw(&multicall_address_error) | ||||||||||||||||||||||||
}); | ||||||||||||||||||||||||
let mut gas_error = "gas, ".to_string(); | ||||||||||||||||||||||||
let gas_value = gas.map(|v| { | ||||||||||||||||||||||||
v.try_into_u256() | ||||||||||||||||||||||||
.inspect_err(|e| gas_error.push_str(&e.to_string())) | ||||||||||||||||||||||||
.expect_throw(&gas_error) | ||||||||||||||||||||||||
}); | ||||||||||||||||||||||||
) -> Result<DoQuoteTargetsResult, QuoteBindingsError> { | ||||||||||||||||||||||||
let multicall_address = multicall_address | ||||||||||||||||||||||||
.map(|v| Address::from_hex(v)) | ||||||||||||||||||||||||
.transpose()?; | ||||||||||||||||||||||||
let gas_value = gas.map(|v| v.try_into_u256()).transpose()?; | ||||||||||||||||||||||||
let quote_targets: Vec<QuoteTarget> = quote_targets | ||||||||||||||||||||||||
.0 | ||||||||||||||||||||||||
.iter() | ||||||||||||||||||||||||
.map(|v| QuoteTarget::from(v.clone())) | ||||||||||||||||||||||||
.collect(); | ||||||||||||||||||||||||
let batch_quote_target = BatchQuoteTarget(quote_targets); | ||||||||||||||||||||||||
match batch_quote_target | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
let quotes = batch_quote_target | ||||||||||||||||||||||||
.do_quote(rpc_url, block_number, gas_value, multicall_address) | ||||||||||||||||||||||||
.await | ||||||||||||||||||||||||
{ | ||||||||||||||||||||||||
Err(e) => Err(e), | ||||||||||||||||||||||||
Ok(v) => Ok(js_sys::Array::from_iter( | ||||||||||||||||||||||||
v.into_iter() | ||||||||||||||||||||||||
.map(|e| e.map_or_else(JsValue::from, JsValue::from)), | ||||||||||||||||||||||||
) | ||||||||||||||||||||||||
.into()), | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
.await?; | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
let res = quotes | ||||||||||||||||||||||||
.into_iter() | ||||||||||||||||||||||||
.map(|q| match q { | ||||||||||||||||||||||||
Ok(v) => QuoteResultEnum::Success { | ||||||||||||||||||||||||
value: v, | ||||||||||||||||||||||||
error: None, | ||||||||||||||||||||||||
}, | ||||||||||||||||||||||||
Err(e) => QuoteResultEnum::Err { | ||||||||||||||||||||||||
value: None, | ||||||||||||||||||||||||
error: e.to_string(), | ||||||||||||||||||||||||
}, | ||||||||||||||||||||||||
}) | ||||||||||||||||||||||||
.collect(); | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
Ok(DoQuoteTargetsResult(res)) | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
/// Given a subgraph url, will fetch the order details from the subgraph and | ||||||||||||||||||||||||
/// then quotes them using the given rpc url. | ||||||||||||||||||||||||
/// Resolves with array of OrderQuoteValue object or a string error | ||||||||||||||||||||||||
#[wasm_bindgen(js_name = "doQuoteSpecs")] | ||||||||||||||||||||||||
#[wasm_export(js_name = "doQuoteSpecs", unchecked_return_type = "DoQuoteSpecsResult")] | ||||||||||||||||||||||||
pub async fn do_quote_specs( | ||||||||||||||||||||||||
quote_specs: &BatchQuoteSpec, | ||||||||||||||||||||||||
subgraph_url: &str, | ||||||||||||||||||||||||
rpc_url: &str, | ||||||||||||||||||||||||
block_number: Option<u64>, | ||||||||||||||||||||||||
gas: Option<js_sys::BigInt>, | ||||||||||||||||||||||||
multicall_address: Option<String>, | ||||||||||||||||||||||||
) -> Result<JsValue, Error> { | ||||||||||||||||||||||||
let mut multicall_address_error = "multicall address, ".to_string(); | ||||||||||||||||||||||||
let multicall_address = multicall_address.map(|v| { | ||||||||||||||||||||||||
Address::from_hex(v) | ||||||||||||||||||||||||
.inspect_err(|e| multicall_address_error.push_str(&e.to_string())) | ||||||||||||||||||||||||
.expect_throw(&multicall_address_error) | ||||||||||||||||||||||||
}); | ||||||||||||||||||||||||
let mut gas_error = "gas, ".to_string(); | ||||||||||||||||||||||||
let gas_value = gas.map(|v| { | ||||||||||||||||||||||||
v.try_into_u256() | ||||||||||||||||||||||||
.inspect_err(|e| gas_error.push_str(&e.to_string())) | ||||||||||||||||||||||||
.expect_throw(&gas_error) | ||||||||||||||||||||||||
}); | ||||||||||||||||||||||||
) -> Result<DoQuoteSpecsResult, QuoteBindingsError> { | ||||||||||||||||||||||||
let multicall_address = multicall_address | ||||||||||||||||||||||||
.map(|v| Address::from_hex(v)) | ||||||||||||||||||||||||
.transpose()?; | ||||||||||||||||||||||||
let gas_value = gas.map(|v| v.try_into_u256()).transpose()?; | ||||||||||||||||||||||||
let quote_specs: Vec<QuoteSpec> = quote_specs | ||||||||||||||||||||||||
.0 | ||||||||||||||||||||||||
.iter() | ||||||||||||||||||||||||
.map(|v| QuoteSpec::from(v.clone())) | ||||||||||||||||||||||||
.collect(); | ||||||||||||||||||||||||
let batch_quote_spec = BatchQuoteSpec(quote_specs); | ||||||||||||||||||||||||
match batch_quote_spec | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
let quotes = batch_quote_spec | ||||||||||||||||||||||||
.do_quote( | ||||||||||||||||||||||||
subgraph_url, | ||||||||||||||||||||||||
rpc_url, | ||||||||||||||||||||||||
block_number, | ||||||||||||||||||||||||
gas_value, | ||||||||||||||||||||||||
multicall_address, | ||||||||||||||||||||||||
) | ||||||||||||||||||||||||
.await | ||||||||||||||||||||||||
{ | ||||||||||||||||||||||||
Err(e) => Err(e), | ||||||||||||||||||||||||
Ok(v) => Ok(js_sys::Array::from_iter( | ||||||||||||||||||||||||
v.into_iter() | ||||||||||||||||||||||||
.map(|e| e.map_or_else(JsValue::from, JsValue::from)), | ||||||||||||||||||||||||
) | ||||||||||||||||||||||||
.into()), | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
.await?; | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
let res = quotes | ||||||||||||||||||||||||
.into_iter() | ||||||||||||||||||||||||
.map(|q| match q { | ||||||||||||||||||||||||
Ok(v) => QuoteResultEnum::Success { | ||||||||||||||||||||||||
value: v, | ||||||||||||||||||||||||
error: None, | ||||||||||||||||||||||||
}, | ||||||||||||||||||||||||
Err(e) => QuoteResultEnum::Err { | ||||||||||||||||||||||||
value: None, | ||||||||||||||||||||||||
error: e.to_string(), | ||||||||||||||||||||||||
}, | ||||||||||||||||||||||||
}) | ||||||||||||||||||||||||
.collect(); | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
Ok(DoQuoteSpecsResult(res)) | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
/// Given a subgraph url, will fetch orders details and returns their | ||||||||||||||||||||||||
/// respective quote targets. | ||||||||||||||||||||||||
/// Resolves with array of QuoteTarget object or undefined if no result | ||||||||||||||||||||||||
/// found on subgraph for a specific spec | ||||||||||||||||||||||||
#[wasm_bindgen(js_name = "getQuoteTargetFromSubgraph")] | ||||||||||||||||||||||||
#[wasm_export( | ||||||||||||||||||||||||
js_name = "getQuoteTargetFromSubgraph", | ||||||||||||||||||||||||
unchecked_return_type = "QuoteTargetResult" | ||||||||||||||||||||||||
)] | ||||||||||||||||||||||||
pub async fn get_batch_quote_target_from_subgraph( | ||||||||||||||||||||||||
quote_specs: &BatchQuoteSpec, | ||||||||||||||||||||||||
subgraph_url: &str, | ||||||||||||||||||||||||
) -> Result<JsValue, Error> { | ||||||||||||||||||||||||
) -> Result<QuoteTargetResult, QuoteBindingsError> { | ||||||||||||||||||||||||
let quote_specs: Vec<QuoteSpec> = quote_specs | ||||||||||||||||||||||||
.0 | ||||||||||||||||||||||||
.iter() | ||||||||||||||||||||||||
.map(|v| QuoteSpec::from(v.clone())) | ||||||||||||||||||||||||
.collect(); | ||||||||||||||||||||||||
let batch_quote_spec = BatchQuoteSpec(quote_specs); | ||||||||||||||||||||||||
match batch_quote_spec | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
let quote_targets = batch_quote_spec | ||||||||||||||||||||||||
.get_batch_quote_target_from_subgraph(subgraph_url) | ||||||||||||||||||||||||
.await | ||||||||||||||||||||||||
{ | ||||||||||||||||||||||||
Err(e) => Err(e), | ||||||||||||||||||||||||
Ok(v) => Ok(to_js_value( | ||||||||||||||||||||||||
&v.into_iter() | ||||||||||||||||||||||||
.map(|e| e.map(QuoteTarget::from)) | ||||||||||||||||||||||||
.collect::<Vec<_>>(), | ||||||||||||||||||||||||
)?), | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
.await?; | ||||||||||||||||||||||||
Ok(QuoteTargetResult(quote_targets)) | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
/// Get the quote for an order | ||||||||||||||||||||||||
/// Resolves with a BatchOrderQuotesResponse object | ||||||||||||||||||||||||
#[wasm_bindgen(js_name = "getOrderQuote")] | ||||||||||||||||||||||||
#[wasm_export( | ||||||||||||||||||||||||
js_name = "getOrderQuote", | ||||||||||||||||||||||||
unchecked_return_type = "DoOrderQuoteResult" | ||||||||||||||||||||||||
)] | ||||||||||||||||||||||||
pub async fn get_order_quote( | ||||||||||||||||||||||||
order: Vec<SgOrder>, | ||||||||||||||||||||||||
rpc_url: &str, | ||||||||||||||||||||||||
block_number: Option<u64>, | ||||||||||||||||||||||||
gas: Option<js_sys::BigInt>, | ||||||||||||||||||||||||
) -> Result<JsValue, Error> { | ||||||||||||||||||||||||
let mut gas_error = "gas, ".to_string(); | ||||||||||||||||||||||||
let gas_value = gas.map(|v| { | ||||||||||||||||||||||||
v.try_into_u256() | ||||||||||||||||||||||||
.inspect_err(|e| gas_error.push_str(&e.to_string())) | ||||||||||||||||||||||||
.expect_throw(&gas_error) | ||||||||||||||||||||||||
}); | ||||||||||||||||||||||||
Ok(to_js_value( | ||||||||||||||||||||||||
&get_order_quotes(order, block_number, rpc_url.to_string(), gas_value).await?, | ||||||||||||||||||||||||
)?) | ||||||||||||||||||||||||
) -> Result<DoOrderQuoteResult, QuoteBindingsError> { | ||||||||||||||||||||||||
let gas_value = gas.map(|v| v.try_into_u256()).transpose()?; | ||||||||||||||||||||||||
let order_quotes = | ||||||||||||||||||||||||
get_order_quotes(order, block_number, rpc_url.to_string(), gas_value).await?; | ||||||||||||||||||||||||
Ok(DoOrderQuoteResult(order_quotes)) | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
#[derive(Error, Debug)] | ||||||||||||||||||||||||
pub enum QuoteBindingsError { | ||||||||||||||||||||||||
#[error(transparent)] | ||||||||||||||||||||||||
QuoteError(#[from] Error), | ||||||||||||||||||||||||
#[error(transparent)] | ||||||||||||||||||||||||
FromHexError(#[from] FromHexError), | ||||||||||||||||||||||||
#[error(transparent)] | ||||||||||||||||||||||||
U256ParseError(#[from] ParseError), | ||||||||||||||||||||||||
#[error(transparent)] | ||||||||||||||||||||||||
SerdeWasmBindgenError(#[from] serde_wasm_bindgen::Error), | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
impl QuoteBindingsError { | ||||||||||||||||||||||||
pub fn to_readable_msg(&self) -> String { | ||||||||||||||||||||||||
match self { | ||||||||||||||||||||||||
Self::QuoteError(e) => format!("Quote error: {}", e), | ||||||||||||||||||||||||
Self::FromHexError(e) => format!("Failed to parse orderbook address: {}", e), | ||||||||||||||||||||||||
Self::U256ParseError(e) => format!("Failed to parse u256 value: {}", e), | ||||||||||||||||||||||||
Self::SerdeWasmBindgenError(err) => format!("Data serialization error: {}", err), | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
Comment on lines
+215
to
+223
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick (assertive)
Manually matching every variant is brittle. Implementing impl std::fmt::Display for QuoteBindingsError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Debug::fmt(self, f)
}
}
impl QuoteBindingsError {
pub fn to_readable_msg(&self) -> String { self.to_string() }
} Reduces maintenance overhead. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No need to do this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @findolor Understood! I'll respect your preference to keep the explicit error message formatting in the |
||||||||||||||||||||||||
|
||||||||||||||||||||||||
impl From<QuoteBindingsError> for JsValue { | ||||||||||||||||||||||||
fn from(value: QuoteBindingsError) -> Self { | ||||||||||||||||||||||||
JsError::new(&value.to_string()).into() | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
Comment on lines
+225
to
+229
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick (assertive) Preserve structured error info when bubbling to JS Wrapping in -fn from(value: QuoteBindingsError) -> Self {
- JsError::new(&value.to_string()).into()
-}
+fn from(value: QuoteBindingsError) -> Self {
+ WasmEncodedError::from(value).into_js_value()
+} This keeps both machine-readable ( 📝 Committable suggestion
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We are not using JsError There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unable to process this comment: maximum number of iterations reached. 🧩 Analysis chain@findolor I see the current implementation does use 🏁 Script executed:
Length of output: 410 @findolor I see that Looking at the original review suggestion, I think I understand your point now - you might want to use the Would you like me to help create a revised suggestion that avoids using 🏁 Script executed:
Length of output: 160 🏁 Script executed:
Length of output: 9475 🏁 Script executed:
Length of output: 256 🏁 Script executed:
Length of output: 509 🏁 Script executed:
Length of output: 599 🏁 Script executed:
Length of output: 2066 🏁 Script executed:
Length of output: 507 🏁 Script executed:
Length of output: 2135 🏁 Script executed:
Length of output: 2778 🧬 Code Graph Analysis ResultsRelevant code snippets for
|
||||||||||||||||||||||||
|
||||||||||||||||||||||||
impl From<QuoteBindingsError> for WasmEncodedError { | ||||||||||||||||||||||||
fn from(value: QuoteBindingsError) -> Self { | ||||||||||||||||||||||||
WasmEncodedError { | ||||||||||||||||||||||||
msg: value.to_string(), | ||||||||||||||||||||||||
readable_msg: value.to_readable_msg(), | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ambiguous untagged enum – serde cannot reliably pick a variant
Both variants expose identical keys (
value
,error
) wrapped inOption
.During deserialization Serde selects the first variant whose fields can be populated, meaning payloads that contain only
error
will still matchSuccess
ifvalue
is omitted – leading to silent logic errors.Recommended fixes:
This guarantees deterministic (de)serialization.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This works with no issues
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@findolor I understand that the current implementation is working for your specific use case. The warning was about a theoretical edge case in Serde's untagged enum deserialization that might not manifest in your particular usage pattern.
Thanks for confirming that it works as intended in your implementation! Let me know if you need any further assistance with the WebAssembly bindings.