use hex_literal::hex; use monero_epee_bin_serde::from_bytes; use serde::de::DeserializeOwned; use serde::Deserialize; use serde_with::serde_as; use serde_with::TryFromInto; use std::convert::TryInto; use std::fmt::Debug; #[test] fn get_o_indexes() { test_from_bytes(&[ (&hex!("011101010101020101140763726564697473050000000000000000096f5f696e64657865738504a900000000000000067374617475730a084f4b08746f705f686173680a0009756e747275737465640b00"), GetOIndexesResponse { base: BaseResponse { credits: 0, status: "OK".to_owned(), top_hash: "".to_string(), untrusted: false, }, o_indexes: vec![169], }), (&hex!("011101010101020101100763726564697473050000000000000000067374617475730a184661696c656408746f705f686173680a0009756e747275737465640b00"), GetOIndexesResponse { base: BaseResponse { credits: 0, status: "Failed".to_owned(), top_hash: "".to_string(), untrusted: false, }, o_indexes: vec![], }) ]) } #[test] fn get_outs() { test_from_bytes(&[ (&hex!("011101010101020101140763726564697473050000000000000000046f7574738c04140668656967687405a100000000000000036b65790a802d392d0be38eb4699c17767e62a063b8d2f989ec15c80e5d2665ab06f8397439046d61736b0a805e8b863c5b267deda13f4bc5d5ec8e59043028380f2431bc8691c15c83e1fea404747869640a80c0646e065a33b849f0d9563673ca48eb0c603fe721dd982720dba463172c246f08756e6c6f636b65640b00067374617475730a084f4b08746f705f686173680a0009756e747275737465640b00"), GetOutsResponse { base: BaseResponse { credits: 0, status: "OK".to_owned(), top_hash: "".to_string(), untrusted: false }, outs: vec![ OutKey { height: 161, key: hex!("2d392d0be38eb4699c17767e62a063b8d2f989ec15c80e5d2665ab06f8397439").try_into().unwrap(), mask: hex!("5e8b863c5b267deda13f4bc5d5ec8e59043028380f2431bc8691c15c83e1fea4").try_into().unwrap(), txid: hex!("c0646e065a33b849f0d9563673ca48eb0c603fe721dd982720dba463172c246f").try_into().unwrap(), unlocked: false } ] }), ]) } fn test_from_bytes(cases: &[(&[u8], T)]) where T: DeserializeOwned + PartialEq + Debug, { for (bytes, expected) in cases { let response = from_bytes::(bytes).unwrap(); assert_eq!(&response, expected) } } #[derive(Clone, Debug, Deserialize, PartialEq)] struct BaseResponse { credits: u64, status: String, top_hash: String, untrusted: bool, } #[derive(Clone, Debug, Deserialize, PartialEq)] struct GetOIndexesResponse { #[serde(flatten)] base: BaseResponse, #[serde(default)] o_indexes: Vec, } #[derive(Clone, Debug, Deserialize, PartialEq)] struct GetOutsResponse { #[serde(flatten)] base: BaseResponse, outs: Vec, } #[serde_as] #[derive(Clone, Copy, Debug, Deserialize, PartialEq)] struct OutKey { height: u64, #[serde_as(as = "TryFromInto<[u8; 32]>")] key: monero::PublicKey, #[serde_as(as = "TryFromInto<[u8; 32]>")] mask: monero::util::ringct::Key, #[serde_as(as = "TryFromInto<[u8; 32]>")] txid: monero::Hash, unlocked: bool, }