use serde::ser::SerializeSeq;
use serde_derive::Serialize;
#[derive(Serialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Response {
#[serde(serialize_with = "crate::hex::as_hex_string")]
pub start_address: u32,
#[serde(serialize_with = "crate::hex::as_hex_string")]
pub size: u32,
pub arch: String,
pub syntax: Vec<String>,
pub instructions: Vec<DecodedInstruction>,
}
#[derive(Debug)]
pub struct DecodedInstruction {
pub offset: u32,
pub decoded_string_per_syntax: Vec<String>,
}
impl serde::Serialize for DecodedInstruction {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut seq = serializer.serialize_seq(None)?;
seq.serialize_element(&self.offset)?;
for decoded_string in &self.decoded_string_per_syntax {
seq.serialize_element(decoded_string)?;
}
seq.end()
}
}
#[cfg(test)]
mod test {
use serde_json::Result;
use super::{DecodedInstruction, Response};
#[test]
fn serialize_correctly() -> Result<()> {
let response = Response {
start_address: 0x1234,
size: 0x3,
arch: "x86_64".to_string(),
syntax: vec!["Intel".to_string()],
instructions: vec![
DecodedInstruction {
offset: 0,
decoded_string_per_syntax: vec!["push rbp".to_string()],
},
DecodedInstruction {
offset: 1,
decoded_string_per_syntax: vec!["mov rbp, rsp".to_string()],
},
],
};
let response = serde_json::to_string_pretty(&response)?;
let expected = r#"{
"startAddress": "0x1234",
"size": "0x3",
"arch": "x86_64",
"syntax": [
"Intel"
],
"instructions": [
[
0,
"push rbp"
],
[
1,
"mov rbp, rsp"
]
]
}"#;
assert_eq!(response, expected);
Ok(())
}
}