use crate::models::ledger::objects::LedgerEntryType;
use crate::models::transactions::PriceData;
use crate::models::{Model, NoFlags};
use alloc::borrow::Cow;
use alloc::vec::Vec;
use serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none;
use super::{CommonFields, LedgerObject};
#[skip_serializing_none]
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
#[serde(rename_all = "PascalCase")]
pub struct Oracle<'a> {
#[serde(flatten)]
pub common_fields: CommonFields<'a, NoFlags>,
pub owner: Cow<'a, str>,
pub provider: Cow<'a, str>,
pub asset_class: Cow<'a, str>,
pub price_data_series: Vec<PriceData>,
pub last_update_time: u32,
#[serde(rename = "URI")]
pub uri: Option<Cow<'a, str>>,
pub owner_node: Cow<'a, str>,
#[serde(rename = "PreviousTxnID")]
pub previous_txn_id: Cow<'a, str>,
pub previous_txn_lgr_seq: u32,
#[serde(rename = "OracleDocumentID")]
pub oracle_document_id: Option<u32>,
}
impl Model for Oracle<'_> {}
impl<'a> LedgerObject<NoFlags> for Oracle<'a> {
fn get_ledger_entry_type(&self) -> LedgerEntryType {
self.common_fields.get_ledger_entry_type()
}
}
#[cfg(test)]
mod test_serde {
use super::*;
use crate::models::transactions::PriceData;
use crate::models::FlagCollection;
use alloc::borrow::Cow;
use alloc::string::ToString;
use alloc::vec;
#[test]
fn test_serialize() {
let oracle = Oracle {
common_fields: CommonFields {
flags: FlagCollection::default(),
ledger_entry_type: LedgerEntryType::Oracle,
index: Some(Cow::from("ForTest")),
ledger_index: None,
},
owner: Cow::from("rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW"),
provider: Cow::from("636861696E6C696E6B"),
asset_class: Cow::from("63757272656E6379"),
price_data_series: vec![PriceData {
base_asset: "XRP".to_string(),
quote_asset: "USD".to_string(),
asset_price: Some("2E4".to_string()),
scale: Some(1),
}],
last_update_time: 743609014,
uri: Some(Cow::from("68747470733A2F2F6578616D706C652E636F6D")),
owner_node: Cow::from("0000000000000000"),
previous_txn_id: Cow::from("ABC123DEF456"),
previous_txn_lgr_seq: 12345678,
oracle_document_id: Some(1),
};
let serialized = serde_json::to_string(&oracle).unwrap();
let deserialized: Oracle = serde_json::from_str(&serialized).unwrap();
assert_eq!(oracle, deserialized);
}
#[test]
fn test_deserialize() {
let json = r#"{
"LedgerEntryType": "Oracle",
"Flags": 0,
"Owner": "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
"Provider": "636861696E6C696E6B",
"AssetClass": "63757272656E6379",
"PriceDataSeries": [
{
"PriceData": {
"BaseAsset": "XRP",
"QuoteAsset": "USD",
"AssetPrice": "2E4",
"Scale": 1
}
}
],
"LastUpdateTime": 743609014,
"URI": "68747470733A2F2F6578616D706C652E636F6D",
"OwnerNode": "0000000000000000",
"PreviousTxnID": "ABC123DEF456",
"PreviousTxnLgrSeq": 12345678,
"OracleDocumentID": 1
}"#;
let oracle: Oracle = serde_json::from_str(json).unwrap();
assert_eq!(oracle.owner, "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW");
assert_eq!(oracle.provider, "636861696E6C696E6B");
assert_eq!(oracle.asset_class, "63757272656E6379");
assert_eq!(oracle.price_data_series.len(), 1);
assert_eq!(oracle.price_data_series[0].base_asset, "XRP");
assert_eq!(oracle.price_data_series[0].quote_asset, "USD");
assert_eq!(oracle.price_data_series[0].asset_price, Some("2E4".into()));
assert_eq!(oracle.price_data_series[0].scale, Some(1));
assert_eq!(oracle.last_update_time, 743609014);
assert_eq!(
oracle.uri,
Some("68747470733A2F2F6578616D706C652E636F6D".into())
);
assert_eq!(oracle.owner_node, "0000000000000000");
assert_eq!(oracle.previous_txn_id, "ABC123DEF456");
assert_eq!(oracle.previous_txn_lgr_seq, 12345678);
assert_eq!(oracle.oracle_document_id, Some(1));
}
#[test]
fn test_new_minimal() {
let oracle = Oracle {
common_fields: CommonFields {
flags: FlagCollection::default(),
ledger_entry_type: LedgerEntryType::Oracle,
index: None,
ledger_index: None,
},
owner: Cow::from("rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW"),
provider: Cow::from("70726F766964657231"),
asset_class: Cow::from("63757272656E6379"),
price_data_series: vec![PriceData {
base_asset: "XRP".to_string(),
quote_asset: "USD".to_string(),
asset_price: Some("2E4".to_string()),
scale: Some(1),
}],
last_update_time: 743609014,
uri: None,
owner_node: Cow::from("0000000000000000"),
previous_txn_id: Cow::from("ABC123"),
previous_txn_lgr_seq: 100,
oracle_document_id: None,
};
assert_eq!(oracle.owner, "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW");
assert_eq!(oracle.provider, "70726F766964657231");
assert_eq!(oracle.asset_class, "63757272656E6379");
assert_eq!(oracle.price_data_series.len(), 1);
assert_eq!(oracle.last_update_time, 743609014);
assert!(oracle.uri.is_none());
assert_eq!(oracle.owner_node, "0000000000000000");
assert_eq!(oracle.previous_txn_id, "ABC123");
assert_eq!(oracle.previous_txn_lgr_seq, 100);
}
#[test]
fn test_ledger_entry_type() {
let oracle = Oracle {
common_fields: CommonFields {
flags: FlagCollection::default(),
ledger_entry_type: LedgerEntryType::Oracle,
index: None,
ledger_index: None,
},
owner: Cow::from("rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW"),
provider: Cow::from("70726F766964657231"),
asset_class: Cow::from("63757272656E6379"),
price_data_series: vec![PriceData {
base_asset: "XRP".to_string(),
quote_asset: "USD".to_string(),
asset_price: Some("2E4".to_string()),
scale: Some(1),
}],
last_update_time: 0,
uri: None,
owner_node: Cow::from("0000000000000000"),
previous_txn_id: Cow::from("ABC123"),
previous_txn_lgr_seq: 0,
oracle_document_id: None,
};
assert_eq!(oracle.get_ledger_entry_type(), LedgerEntryType::Oracle);
}
#[test]
fn test_with_multiple_price_data() {
let oracle = Oracle {
common_fields: CommonFields {
flags: FlagCollection::default(),
ledger_entry_type: LedgerEntryType::Oracle,
index: Some(Cow::from("TestIndex")),
ledger_index: None,
},
owner: Cow::from("rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW"),
provider: Cow::from("636861696E6C696E6B"),
asset_class: Cow::from("63757272656E6379"),
price_data_series: vec![
PriceData {
base_asset: "XRP".to_string(),
quote_asset: "USD".to_string(),
asset_price: Some("2E4".to_string()),
scale: Some(1),
},
PriceData {
base_asset: "BTC".to_string(),
quote_asset: "USD".to_string(),
asset_price: Some("27AC40".to_string()),
scale: Some(2),
},
PriceData {
base_asset: "ETH".to_string(),
quote_asset: "USD".to_string(),
asset_price: Some("27100".to_string()),
scale: Some(2),
},
],
last_update_time: 743609014,
uri: Some(Cow::from("68747470733A2F2F6578616D706C652E636F6D")),
owner_node: Cow::from("0000000000000000"),
previous_txn_id: Cow::from("DEF789"),
previous_txn_lgr_seq: 99999,
oracle_document_id: None,
};
let series = oracle.price_data_series;
assert_eq!(series.len(), 3);
assert_eq!(series[0].base_asset, "XRP");
assert_eq!(series[1].base_asset, "BTC");
assert_eq!(series[2].base_asset, "ETH");
}
}