Skip to content

Commit a0d108f

Browse files
committed
fix: human readable de/ser for versioned message
1 parent 2d88eb4 commit a0d108f

File tree

1 file changed

+94
-23
lines changed

1 file changed

+94
-23
lines changed

message/src/versions/mod.rs

Lines changed: 94 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -181,17 +181,35 @@ impl serde::Serialize for VersionedMessage {
181181
where
182182
S: Serializer,
183183
{
184-
match self {
185-
Self::Legacy(message) => {
186-
let mut seq = serializer.serialize_tuple(1)?;
187-
seq.serialize_element(message)?;
188-
seq.end()
184+
if serializer.is_human_readable() {
185+
#[derive(Serialize)]
186+
#[serde(tag = "version")]
187+
enum HR<'a> {
188+
#[serde(rename = "legacy")]
189+
Legacy { message: &'a LegacyMessage },
190+
#[serde(rename = "0")]
191+
V0 { message: &'a v0::Message },
189192
}
190-
Self::V0(message) => {
191-
let mut seq = serializer.serialize_tuple(2)?;
192-
seq.serialize_element(&MESSAGE_VERSION_PREFIX)?;
193-
seq.serialize_element(message)?;
194-
seq.end()
193+
194+
let hr = match self {
195+
Self::Legacy(message) => HR::Legacy { message },
196+
Self::V0(message) => HR::V0 { message },
197+
};
198+
199+
HR::serialize(&hr, serializer)
200+
} else {
201+
match self {
202+
Self::Legacy(message) => {
203+
let mut seq = serializer.serialize_tuple(1)?;
204+
seq.serialize_element(message)?;
205+
seq.end()
206+
}
207+
Self::V0(message) => {
208+
let mut seq = serializer.serialize_tuple(2)?;
209+
seq.serialize_element(&MESSAGE_VERSION_PREFIX)?;
210+
seq.serialize_element(message)?;
211+
seq.end()
212+
}
195213
}
196214
}
197215
}
@@ -247,7 +265,6 @@ impl<'de> serde::Deserialize<'de> for VersionedMessage {
247265
D: Deserializer<'de>,
248266
{
249267
struct MessageVisitor;
250-
251268
impl<'de> Visitor<'de> for MessageVisitor {
252269
type Value = VersionedMessage;
253270

@@ -262,7 +279,6 @@ impl<'de> serde::Deserialize<'de> for VersionedMessage {
262279
let prefix: MessagePrefix = seq
263280
.next_element()?
264281
.ok_or_else(|| de::Error::invalid_length(0, &self))?;
265-
266282
match prefix {
267283
MessagePrefix::Legacy(num_required_signatures) => {
268284
// The remaining fields of the legacy Message struct after the first byte.
@@ -322,7 +338,23 @@ impl<'de> serde::Deserialize<'de> for VersionedMessage {
322338
}
323339
}
324340

325-
deserializer.deserialize_tuple(2, MessageVisitor)
341+
if deserializer.is_human_readable() {
342+
#[derive(Deserialize)]
343+
#[serde(tag = "version")]
344+
enum HR {
345+
#[serde(rename = "legacy")]
346+
Legacy { message: LegacyMessage },
347+
#[serde(rename = "0")]
348+
V0 { message: v0::Message },
349+
}
350+
351+
match HR::deserialize(deserializer)? {
352+
HR::Legacy { message } => Ok(VersionedMessage::Legacy(message)),
353+
HR::V0 { message } => Ok(VersionedMessage::V0(message)),
354+
}
355+
} else {
356+
deserializer.deserialize_tuple(2, MessageVisitor)
357+
}
326358
}
327359
}
328360

@@ -334,6 +366,23 @@ mod tests {
334366
solana_instruction::{AccountMeta, Instruction},
335367
};
336368

369+
#[test]
370+
fn test_versioned_message_human_readable_serialization() {
371+
let message = LegacyMessage::default();
372+
let message_string = serde_json::to_string(&message).unwrap();
373+
let string = serde_json::to_string(&VersionedMessage::Legacy(message)).unwrap();
374+
let expected_string = format!(r#"{{"version":"legacy","message":{}}}"#, message_string);
375+
assert_eq!(string, expected_string);
376+
377+
let message = v0::Message::default();
378+
let message_string = serde_json::to_string(&message).unwrap();
379+
let string = serde_json::to_string(&VersionedMessage::V0(message)).unwrap();
380+
assert_eq!(
381+
string,
382+
format!(r#"{{"version":"0","message":{}}}"#, message_string)
383+
);
384+
}
385+
337386
#[test]
338387
fn test_legacy_message_serialization() {
339388
let program_id0 = Address::new_unique();
@@ -367,10 +416,10 @@ mod tests {
367416
assert_eq!(bytes, bincode::serialize(&wrapped_message).unwrap());
368417

369418
let message_from_bytes: LegacyMessage = bincode::deserialize(&bytes).unwrap();
419+
assert_eq!(message, message_from_bytes);
420+
370421
let wrapped_message_from_bytes: VersionedMessage =
371422
bincode::deserialize(&bytes).unwrap();
372-
373-
assert_eq!(message, message_from_bytes);
374423
assert_eq!(wrapped_message, wrapped_message_from_bytes);
375424
}
376425

@@ -379,12 +428,17 @@ mod tests {
379428
let string = serde_json::to_string(&message).unwrap();
380429
let message_from_string: LegacyMessage = serde_json::from_str(&string).unwrap();
381430
assert_eq!(message, message_from_string);
431+
432+
let wrapped_string = serde_json::to_string(&wrapped_message).unwrap();
433+
let wrapped_message_from_string: VersionedMessage =
434+
serde_json::from_str(&wrapped_string).unwrap();
435+
assert_eq!(wrapped_message, wrapped_message_from_string);
382436
}
383437
}
384438

385439
#[test]
386440
fn test_versioned_message_serialization() {
387-
let message = VersionedMessage::V0(v0::Message {
441+
let message = v0::Message {
388442
header: MessageHeader {
389443
num_required_signatures: 1,
390444
num_readonly_signed_accounts: 0,
@@ -409,14 +463,31 @@ mod tests {
409463
accounts: vec![0, 2, 3, 4],
410464
data: vec![],
411465
}],
412-
});
466+
};
467+
let wrapped_message = VersionedMessage::V0(message.clone());
413468

414-
let bytes = bincode::serialize(&message).unwrap();
415-
let message_from_bytes: VersionedMessage = bincode::deserialize(&bytes).unwrap();
416-
assert_eq!(message, message_from_bytes);
469+
// bincode
470+
{
471+
let bytes = bincode::serialize(&message).unwrap();
472+
let message_from_bytes: v0::Message = bincode::deserialize(&bytes).unwrap();
473+
assert_eq!(message, message_from_bytes);
417474

418-
let string = serde_json::to_string(&message).unwrap();
419-
let message_from_string: VersionedMessage = serde_json::from_str(&string).unwrap();
420-
assert_eq!(message, message_from_string);
475+
let wrapped_bytes = bincode::serialize(&wrapped_message).unwrap();
476+
let wrapped_message_from_bytes: VersionedMessage =
477+
bincode::deserialize(&wrapped_bytes).unwrap();
478+
assert_eq!(wrapped_message, wrapped_message_from_bytes);
479+
}
480+
481+
// serde_json
482+
{
483+
let string = serde_json::to_string(&message).unwrap();
484+
let message_from_string: v0::Message = serde_json::from_str(&string).unwrap();
485+
assert_eq!(message, message_from_string);
486+
487+
let wrapped_string = serde_json::to_string(&wrapped_message).unwrap();
488+
let wrapped_message_from_string: VersionedMessage =
489+
serde_json::from_str(&wrapped_string).unwrap();
490+
assert_eq!(wrapped_message, wrapped_message_from_string);
491+
}
421492
}
422493
}

0 commit comments

Comments
 (0)