xrpl/models/ledger/objects/
oracle.rs1use crate::models::ledger::objects::LedgerEntryType;
2use crate::models::transactions::PriceData;
3use crate::models::{Model, NoFlags};
4use alloc::borrow::Cow;
5use alloc::vec::Vec;
6use serde::{Deserialize, Serialize};
7use serde_with::skip_serializing_none;
8
9use super::{CommonFields, LedgerObject};
10
11#[skip_serializing_none]
16#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
17#[serde(rename_all = "PascalCase")]
18pub struct Oracle<'a> {
19 #[serde(flatten)]
24 pub common_fields: CommonFields<'a, NoFlags>,
25 pub owner: Cow<'a, str>,
27 pub provider: Cow<'a, str>,
29 pub asset_class: Cow<'a, str>,
31 pub price_data_series: Vec<PriceData>,
33 pub last_update_time: u32,
35 #[serde(rename = "URI")]
37 pub uri: Option<Cow<'a, str>>,
38 pub owner_node: Cow<'a, str>,
40 #[serde(rename = "PreviousTxnID")]
42 pub previous_txn_id: Cow<'a, str>,
43 pub previous_txn_lgr_seq: u32,
46 #[serde(rename = "OracleDocumentID")]
49 pub oracle_document_id: Option<u32>,
50}
51
52impl Model for Oracle<'_> {}
53
54impl<'a> LedgerObject<NoFlags> for Oracle<'a> {
55 fn get_ledger_entry_type(&self) -> LedgerEntryType {
56 self.common_fields.get_ledger_entry_type()
57 }
58}
59
60#[cfg(test)]
61mod test_serde {
62 use super::*;
63 use crate::models::transactions::PriceData;
64 use crate::models::FlagCollection;
65 use alloc::borrow::Cow;
66 use alloc::string::ToString;
67 use alloc::vec;
68
69 #[test]
70 fn test_serialize() {
71 let oracle = Oracle {
72 common_fields: CommonFields {
73 flags: FlagCollection::default(),
74 ledger_entry_type: LedgerEntryType::Oracle,
75 index: Some(Cow::from("ForTest")),
76 ledger_index: None,
77 },
78 owner: Cow::from("rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW"),
79 provider: Cow::from("636861696E6C696E6B"),
80 asset_class: Cow::from("63757272656E6379"),
81 price_data_series: vec![PriceData {
82 base_asset: "XRP".to_string(),
83 quote_asset: "USD".to_string(),
84 asset_price: Some("2E4".to_string()),
85 scale: Some(1),
86 }],
87 last_update_time: 743609014,
88 uri: Some(Cow::from("68747470733A2F2F6578616D706C652E636F6D")),
89 owner_node: Cow::from("0000000000000000"),
90 previous_txn_id: Cow::from("ABC123DEF456"),
91 previous_txn_lgr_seq: 12345678,
92 oracle_document_id: Some(1),
93 };
94
95 let serialized = serde_json::to_string(&oracle).unwrap();
96 let deserialized: Oracle = serde_json::from_str(&serialized).unwrap();
97 assert_eq!(oracle, deserialized);
98 }
99
100 #[test]
101 fn test_deserialize() {
102 let json = r#"{
103 "LedgerEntryType": "Oracle",
104 "Flags": 0,
105 "Owner": "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
106 "Provider": "636861696E6C696E6B",
107 "AssetClass": "63757272656E6379",
108 "PriceDataSeries": [
109 {
110 "PriceData": {
111 "BaseAsset": "XRP",
112 "QuoteAsset": "USD",
113 "AssetPrice": "2E4",
114 "Scale": 1
115 }
116 }
117 ],
118 "LastUpdateTime": 743609014,
119 "URI": "68747470733A2F2F6578616D706C652E636F6D",
120 "OwnerNode": "0000000000000000",
121 "PreviousTxnID": "ABC123DEF456",
122 "PreviousTxnLgrSeq": 12345678,
123 "OracleDocumentID": 1
124 }"#;
125
126 let oracle: Oracle = serde_json::from_str(json).unwrap();
127 assert_eq!(oracle.owner, "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW");
128 assert_eq!(oracle.provider, "636861696E6C696E6B");
129 assert_eq!(oracle.asset_class, "63757272656E6379");
130 assert_eq!(oracle.price_data_series.len(), 1);
131 assert_eq!(oracle.price_data_series[0].base_asset, "XRP");
132 assert_eq!(oracle.price_data_series[0].quote_asset, "USD");
133 assert_eq!(oracle.price_data_series[0].asset_price, Some("2E4".into()));
134 assert_eq!(oracle.price_data_series[0].scale, Some(1));
135 assert_eq!(oracle.last_update_time, 743609014);
136 assert_eq!(
137 oracle.uri,
138 Some("68747470733A2F2F6578616D706C652E636F6D".into())
139 );
140 assert_eq!(oracle.owner_node, "0000000000000000");
141 assert_eq!(oracle.previous_txn_id, "ABC123DEF456");
142 assert_eq!(oracle.previous_txn_lgr_seq, 12345678);
143 assert_eq!(oracle.oracle_document_id, Some(1));
144 }
145
146 #[test]
147 fn test_new_minimal() {
148 let oracle = Oracle {
149 common_fields: CommonFields {
150 flags: FlagCollection::default(),
151 ledger_entry_type: LedgerEntryType::Oracle,
152 index: None,
153 ledger_index: None,
154 },
155 owner: Cow::from("rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW"),
156 provider: Cow::from("70726F766964657231"),
157 asset_class: Cow::from("63757272656E6379"),
158 price_data_series: vec![PriceData {
159 base_asset: "XRP".to_string(),
160 quote_asset: "USD".to_string(),
161 asset_price: Some("2E4".to_string()),
162 scale: Some(1),
163 }],
164 last_update_time: 743609014,
165 uri: None,
166 owner_node: Cow::from("0000000000000000"),
167 previous_txn_id: Cow::from("ABC123"),
168 previous_txn_lgr_seq: 100,
169 oracle_document_id: None,
170 };
171
172 assert_eq!(oracle.owner, "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW");
173 assert_eq!(oracle.provider, "70726F766964657231");
174 assert_eq!(oracle.asset_class, "63757272656E6379");
175 assert_eq!(oracle.price_data_series.len(), 1);
176 assert_eq!(oracle.last_update_time, 743609014);
177 assert!(oracle.uri.is_none());
178 assert_eq!(oracle.owner_node, "0000000000000000");
179 assert_eq!(oracle.previous_txn_id, "ABC123");
180 assert_eq!(oracle.previous_txn_lgr_seq, 100);
181 }
182
183 #[test]
184 fn test_ledger_entry_type() {
185 let oracle = Oracle {
186 common_fields: CommonFields {
187 flags: FlagCollection::default(),
188 ledger_entry_type: LedgerEntryType::Oracle,
189 index: None,
190 ledger_index: None,
191 },
192 owner: Cow::from("rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW"),
193 provider: Cow::from("70726F766964657231"),
194 asset_class: Cow::from("63757272656E6379"),
195 price_data_series: vec![PriceData {
196 base_asset: "XRP".to_string(),
197 quote_asset: "USD".to_string(),
198 asset_price: Some("2E4".to_string()),
199 scale: Some(1),
200 }],
201 last_update_time: 0,
202 uri: None,
203 owner_node: Cow::from("0000000000000000"),
204 previous_txn_id: Cow::from("ABC123"),
205 previous_txn_lgr_seq: 0,
206 oracle_document_id: None,
207 };
208
209 assert_eq!(oracle.get_ledger_entry_type(), LedgerEntryType::Oracle);
210 }
211
212 #[test]
213 fn test_with_multiple_price_data() {
214 let oracle = Oracle {
215 common_fields: CommonFields {
216 flags: FlagCollection::default(),
217 ledger_entry_type: LedgerEntryType::Oracle,
218 index: Some(Cow::from("TestIndex")),
219 ledger_index: None,
220 },
221 owner: Cow::from("rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW"),
222 provider: Cow::from("636861696E6C696E6B"),
223 asset_class: Cow::from("63757272656E6379"),
224 price_data_series: vec![
225 PriceData {
226 base_asset: "XRP".to_string(),
227 quote_asset: "USD".to_string(),
228 asset_price: Some("2E4".to_string()),
229 scale: Some(1),
230 },
231 PriceData {
232 base_asset: "BTC".to_string(),
233 quote_asset: "USD".to_string(),
234 asset_price: Some("27AC40".to_string()),
235 scale: Some(2),
236 },
237 PriceData {
238 base_asset: "ETH".to_string(),
239 quote_asset: "USD".to_string(),
240 asset_price: Some("27100".to_string()),
241 scale: Some(2),
242 },
243 ],
244 last_update_time: 743609014,
245 uri: Some(Cow::from("68747470733A2F2F6578616D706C652E636F6D")),
246 owner_node: Cow::from("0000000000000000"),
247 previous_txn_id: Cow::from("DEF789"),
248 previous_txn_lgr_seq: 99999,
249 oracle_document_id: None,
250 };
251
252 let series = oracle.price_data_series;
253 assert_eq!(series.len(), 3);
254 assert_eq!(series[0].base_asset, "XRP");
255 assert_eq!(series[1].base_asset, "BTC");
256 assert_eq!(series[2].base_asset, "ETH");
257 }
258}