Skip to content

Commit ba37036

Browse files
authored
Merge pull request #145 from hyperware-ai/hf/serialize-lazy-load-blob-and-send-error
add (de)serialization methods for blob & SendError
2 parents 1c3bd9b + b7c9d27 commit ba37036

File tree

4 files changed

+101
-1
lines changed

4 files changed

+101
-1
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ alloy = { version = "0.8.1", features = [
2222
"rpc-types",
2323
] }
2424
anyhow = "1.0"
25+
base64 = "0.22.1"
2526
bincode = "1.3.3"
2627
color-eyre = { version = "0.6", features = ["capture-spantrace"], optional = true }
2728
http = "1.0.0"

src/types/lazy_load_blob.rs

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
use std::fmt;
2+
use std::marker::PhantomData;
3+
4+
use base64::{engine::general_purpose::STANDARD as BASE64, Engine as _};
5+
use serde::de::{self, Visitor};
6+
use serde::{Deserialize, Deserializer, Serialize, Serializer};
7+
18
pub use crate::LazyLoadBlob;
29

310
/// `LazyLoadBlob` is defined in the wit bindings, but constructors and methods here.
@@ -42,3 +49,94 @@ impl std::cmp::PartialEq for LazyLoadBlob {
4249
self.mime == other.mime && self.bytes == other.bytes
4350
}
4451
}
52+
53+
impl Serialize for LazyLoadBlob {
54+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
55+
where
56+
S: Serializer,
57+
{
58+
// Create a struct with 2 fields
59+
use serde::ser::SerializeStruct;
60+
let mut state = serializer.serialize_struct("LazyLoadBlob", 2)?;
61+
62+
// Serialize mime normally (serde handles Option automatically)
63+
state.serialize_field("mime", &self.mime)?;
64+
65+
let base64_data = BASE64.encode(&self.bytes);
66+
state.serialize_field("bytes", &base64_data)?;
67+
68+
state.end()
69+
}
70+
}
71+
72+
// Custom visitor for deserialization
73+
struct LazyLoadBlobVisitor {
74+
marker: PhantomData<fn() -> LazyLoadBlob>,
75+
}
76+
77+
impl LazyLoadBlobVisitor {
78+
fn new() -> Self {
79+
LazyLoadBlobVisitor {
80+
marker: PhantomData,
81+
}
82+
}
83+
}
84+
85+
impl<'de> Visitor<'de> for LazyLoadBlobVisitor {
86+
type Value = LazyLoadBlob;
87+
88+
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
89+
formatter.write_str("a struct with mime and bytes fields")
90+
}
91+
92+
fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
93+
where
94+
M: de::MapAccess<'de>,
95+
{
96+
let mut mime = None;
97+
let mut bytes_base64 = None;
98+
99+
// Extract each field from the map
100+
while let Some(key) = map.next_key::<String>()? {
101+
match key.as_str() {
102+
"mime" => {
103+
if mime.is_some() {
104+
return Err(de::Error::duplicate_field("mime"));
105+
}
106+
mime = map.next_value()?;
107+
}
108+
"bytes" => {
109+
if bytes_base64.is_some() {
110+
return Err(de::Error::duplicate_field("bytes"));
111+
}
112+
bytes_base64 = Some(map.next_value::<String>()?);
113+
}
114+
_ => {
115+
// Skip unknown fields
116+
let _ = map.next_value::<de::IgnoredAny>()?;
117+
}
118+
}
119+
}
120+
121+
let bytes_base64 = bytes_base64.ok_or_else(|| de::Error::missing_field("bytes"))?;
122+
123+
let bytes = BASE64
124+
.decode(bytes_base64.as_bytes())
125+
.map_err(|err| de::Error::custom(format!("Invalid base64: {}", err)))?;
126+
127+
Ok(LazyLoadBlob { mime, bytes })
128+
}
129+
}
130+
131+
impl<'de> Deserialize<'de> for LazyLoadBlob {
132+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
133+
where
134+
D: Deserializer<'de>,
135+
{
136+
deserializer.deserialize_struct(
137+
"LazyLoadBlob",
138+
&["mime", "bytes"],
139+
LazyLoadBlobVisitor::new(),
140+
)
141+
}
142+
}

src/types/send_error.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::{Address, LazyLoadBlob, Message, _wit_message_to_message};
22
use serde::{Deserialize, Serialize};
33

4-
#[derive(Debug, Clone)]
4+
#[derive(Debug, Clone, Deserialize, Serialize)]
55
pub struct SendError {
66
pub kind: SendErrorKind,
77
pub target: Address,

0 commit comments

Comments
 (0)