Skip to content

Commit 2bfa627

Browse files
authored
Merge pull request #144 from hyperware-ai/develop
develop 1.1.0
2 parents 33118ab + 5707c33 commit 2bfa627

File tree

8 files changed

+114
-6
lines changed

8 files changed

+114
-6
lines changed

Cargo.lock

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "hyperware_process_lib"
33
authors = ["Sybil Technologies AG"]
4-
version = "1.0.6"
4+
version = "1.1.0"
55
edition = "2021"
66
description = "A library for writing Hyperware processes in Rust."
77
homepage = "https://hyperware.ai"
@@ -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/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ pub use types::{
7777
address::{Address, AddressParseError},
7878
capability::Capability,
7979
lazy_load_blob::LazyLoadBlob,
80-
message::{Message, _wit_message_to_message},
80+
message::{BuildError, Message, _wit_message_to_message},
8181
on_exit::OnExit,
8282
package_id::PackageId,
8383
process_id::{ProcessId, ProcessIdParseError},

src/logging.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,14 @@ pub struct TerminalWriterMaker {
4242

4343
impl std::io::Write for RemoteWriter {
4444
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
45-
let body = serde_json::json!({"Log": buf});
45+
let log = if let Ok(json_log) = serde_json::from_slice::<serde_json::Value>(buf) {
46+
serde_json::to_string(&json_log).unwrap()
47+
} else {
48+
let string = String::from_utf8(buf.to_vec())
49+
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?;
50+
string
51+
};
52+
let body = serde_json::json!({"Log": log});
4653
let body = serde_json::to_vec(&body).unwrap();
4754
Request::to(&self.target).body(body).send().unwrap();
4855
Ok(buf.len())

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/message.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ pub enum Message {
2727
},
2828
}
2929

30-
#[derive(Debug, Error, Serialize, Deserialize)]
30+
#[derive(Clone, Debug, Error, Serialize, Deserialize)]
3131
pub enum BuildError {
3232
#[error("no body set for message")]
3333
NoBody,

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,

src/vfs/file.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::{get_blob, PackageId};
66
/// VFS (Virtual File System) helper struct for a file.
77
/// Opening or creating a `File` will give you a `Result<File, VfsError>`.
88
/// You can call its impl functions to interact with it.
9+
#[derive(serde::Deserialize, serde::Serialize)]
910
pub struct File {
1011
pub path: String,
1112
pub timeout: u64,

0 commit comments

Comments
 (0)