use alloc::borrow::Cow;
use serde::{Deserialize, Serialize};
use crate::models::Amount;
#[serde_with::skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
pub struct BookOffers<'a> {
pub offers: Cow<'a, [BookOffer<'a>]>,
pub ledger_hash: Option<Cow<'a, str>>,
pub ledger_index: Option<u32>,
pub ledger_current_index: Option<u32>,
}
#[serde_with::skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
#[serde(rename_all = "PascalCase")]
pub struct BookOffer<'a> {
pub flags: u32,
#[serde(rename = "quality")]
pub quality: Cow<'a, str>,
#[serde(rename = "index")]
pub index: Cow<'a, str>,
pub taker_gets: Amount<'a>,
pub taker_gets_funded: Option<Amount<'a>>,
pub taker_pays: Amount<'a>,
pub taker_pays_funded: Option<Amount<'a>>,
pub account: Cow<'a, str>,
pub owner_funds: Option<Cow<'a, str>>,
pub book_directory: Cow<'a, str>,
pub book_node: Option<Cow<'a, str>>,
pub expiration: Option<u32>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_book_offers_deserialization() {
let json = r#"{
"ledger_current_index": 7035305,
"offers": [
{
"Account": "rM3X3QSr8icjTGpaF52dozhbT2BZSXJQYM",
"BookDirectory": "7E5F614417C2D0A7CEFEB73C4AA773ED5B078DE2B5771F6D55055E4C405218EB",
"BookNode": "0000000000000000",
"Flags": 0,
"LedgerEntryType": "Offer",
"OwnerNode": "0000000000000AE0",
"PreviousTxnID": "6956221794397C25A53647182E5C78A439766D600724074C99D78982E37599F1",
"PreviousTxnLgrSeq": 7022646,
"Sequence": 264542,
"TakerGets": {
"currency": "EUR",
"issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
"value": "17.90363633316433"
},
"TakerPays": {
"currency": "USD",
"issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
"value": "27.05340557506234"
},
"index": "96A9104BF3137131FF8310B9174F3B37170E2144C813CA2A1695DF2C5677E811",
"quality": "1.511056473200875"
},
{
"Account": "rhsxKNyN99q6vyYCTHNTC1TqWCeHr7PNgp",
"BookDirectory": "7E5F614417C2D0A7CEFEB73C4AA773ED5B078DE2B5771F6D5505DCAA8FE12000",
"BookNode": "0000000000000000",
"Flags": 131072,
"LedgerEntryType": "Offer",
"OwnerNode": "0000000000000001",
"PreviousTxnID": "8AD748CD489F7FF34FCD4FB73F77F1901E27A6EFA52CCBB0CCDAAB934E5E754D",
"PreviousTxnLgrSeq": 7007546,
"Sequence": 265,
"TakerGets": {
"currency": "EUR",
"issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
"value": "2.542743233917848"
},
"TakerPays": {
"currency": "USD",
"issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
"value": "4.19552633596446"
},
"index": "7001797678E886E22D6DE11AF90DF1E08F4ADC21D763FAFB36AF66894D695235",
"quality": "1.65"
}
]
}"#;
let book_offers: BookOffers = serde_json::from_str(json).unwrap();
assert_eq!(book_offers.ledger_current_index, Some(7035305));
assert_eq!(book_offers.ledger_hash, None);
assert_eq!(book_offers.ledger_index, None);
assert_eq!(book_offers.offers.len(), 2);
let first_offer = &book_offers.offers[0];
assert_eq!(first_offer.flags, 0);
assert_eq!(first_offer.quality, "1.511056473200875");
assert_eq!(
first_offer.book_directory,
"7E5F614417C2D0A7CEFEB73C4AA773ED5B078DE2B5771F6D55055E4C405218EB"
);
assert_eq!(first_offer.book_node, Some(Cow::from("0000000000000000")));
assert_eq!(first_offer.account, "rM3X3QSr8icjTGpaF52dozhbT2BZSXJQYM");
if let Amount::IssuedCurrencyAmount(amount) = &first_offer.taker_gets {
assert_eq!(amount.currency, "EUR");
assert_eq!(amount.issuer, "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B");
assert_eq!(amount.value, "17.90363633316433");
} else {
panic!("Expected IssuedCurrencyAmount for taker_gets");
}
if let Amount::IssuedCurrencyAmount(amount) = &first_offer.taker_pays {
assert_eq!(amount.currency, "USD");
assert_eq!(amount.issuer, "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B");
assert_eq!(amount.value, "27.05340557506234");
} else {
panic!("Expected IssuedCurrencyAmount for taker_pays");
}
let second_offer = &book_offers.offers[1];
assert_eq!(second_offer.flags, 131072);
assert_eq!(second_offer.quality, "1.65");
assert_eq!(
second_offer.book_directory,
"7E5F614417C2D0A7CEFEB73C4AA773ED5B078DE2B5771F6D5505DCAA8FE12000"
);
assert_eq!(second_offer.book_node, Some(Cow::from("0000000000000000")));
assert_eq!(second_offer.account, "rhsxKNyN99q6vyYCTHNTC1TqWCeHr7PNgp");
if let Amount::IssuedCurrencyAmount(amount) = &second_offer.taker_gets {
assert_eq!(amount.currency, "EUR");
assert_eq!(amount.issuer, "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B");
assert_eq!(amount.value, "2.542743233917848");
} else {
panic!("Expected IssuedCurrencyAmount for taker_gets");
}
if let Amount::IssuedCurrencyAmount(amount) = &second_offer.taker_pays {
assert_eq!(amount.currency, "USD");
assert_eq!(amount.issuer, "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B");
assert_eq!(amount.value, "4.19552633596446");
} else {
panic!("Expected IssuedCurrencyAmount for taker_pays");
}
}
}