1use super::*;
3use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, PartialEq)]
7#[non_exhaustive]
8pub enum Order {
9 MarketOrder(MarketOrder),
11 LimitOrder(LimitOrder),
13 StopOrder(StopOrder),
15 MarketIfTouchedOrder(MarketIfTouchedOrder),
17 TakeProfitOrder(TakeProfitOrder),
19 StopLossOrder(StopLossOrder),
21 GuaranteedStopLossOrder(GuaranteedStopLossOrder),
23 TrailingStopLossOrder(TrailingStopLossOrder),
25 FixedPriceOrder(FixedPriceOrder),
27 Unknown {
29 kind: String,
31 raw: serde_json::Value,
33 },
34}
35
36impl<'de> Deserialize<'de> for Order {
37 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
38 let value = serde_json::Value::deserialize(deserializer)?;
39 let kind = value
40 .get("type")
41 .and_then(serde_json::Value::as_str)
42 .ok_or_else(|| serde::de::Error::custom("missing OANDA type discriminator"))?;
43 match kind {
44 "MARKET" => serde_json::from_value(value)
45 .map(Self::MarketOrder)
46 .map_err(serde::de::Error::custom),
47 "LIMIT" => serde_json::from_value(value)
48 .map(Self::LimitOrder)
49 .map_err(serde::de::Error::custom),
50 "STOP" => serde_json::from_value(value)
51 .map(Self::StopOrder)
52 .map_err(serde::de::Error::custom),
53 "MARKET_IF_TOUCHED" => serde_json::from_value(value)
54 .map(Self::MarketIfTouchedOrder)
55 .map_err(serde::de::Error::custom),
56 "TAKE_PROFIT" => serde_json::from_value(value)
57 .map(Self::TakeProfitOrder)
58 .map_err(serde::de::Error::custom),
59 "STOP_LOSS" => serde_json::from_value(value)
60 .map(Self::StopLossOrder)
61 .map_err(serde::de::Error::custom),
62 "GUARANTEED_STOP_LOSS" => serde_json::from_value(value)
63 .map(Self::GuaranteedStopLossOrder)
64 .map_err(serde::de::Error::custom),
65 "TRAILING_STOP_LOSS" => serde_json::from_value(value)
66 .map(Self::TrailingStopLossOrder)
67 .map_err(serde::de::Error::custom),
68 "FIXED_PRICE" => serde_json::from_value(value)
69 .map(Self::FixedPriceOrder)
70 .map_err(serde::de::Error::custom),
71 other => Ok(Self::Unknown {
72 kind: other.to_owned(),
73 raw: value,
74 }),
75 }
76 }
77}
78
79impl Serialize for Order {
80 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
81 let (kind, mut value) = match self {
82 Self::MarketOrder(body) => (
83 "MARKET",
84 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
85 ),
86 Self::LimitOrder(body) => (
87 "LIMIT",
88 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
89 ),
90 Self::StopOrder(body) => (
91 "STOP",
92 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
93 ),
94 Self::MarketIfTouchedOrder(body) => (
95 "MARKET_IF_TOUCHED",
96 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
97 ),
98 Self::TakeProfitOrder(body) => (
99 "TAKE_PROFIT",
100 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
101 ),
102 Self::StopLossOrder(body) => (
103 "STOP_LOSS",
104 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
105 ),
106 Self::GuaranteedStopLossOrder(body) => (
107 "GUARANTEED_STOP_LOSS",
108 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
109 ),
110 Self::TrailingStopLossOrder(body) => (
111 "TRAILING_STOP_LOSS",
112 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
113 ),
114 Self::FixedPriceOrder(body) => (
115 "FIXED_PRICE",
116 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
117 ),
118 Self::Unknown { kind, raw } => (kind.as_str(), raw.clone()),
119 };
120 let object = value
121 .as_object_mut()
122 .ok_or_else(|| serde::ser::Error::custom("OANDA variant must be an object"))?;
123 object.insert(
124 "type".to_owned(),
125 serde_json::Value::String(kind.to_owned()),
126 );
127 value.serialize(serializer)
128 }
129}
130
131#[derive(Debug, Clone, PartialEq)]
133#[non_exhaustive]
134pub enum OrderRequest {
135 MarketOrderRequest(MarketOrderRequest),
137 LimitOrderRequest(LimitOrderRequest),
139 StopOrderRequest(StopOrderRequest),
141 MarketIfTouchedOrderRequest(MarketIfTouchedOrderRequest),
143 TakeProfitOrderRequest(TakeProfitOrderRequest),
145 StopLossOrderRequest(StopLossOrderRequest),
147 GuaranteedStopLossOrderRequest(GuaranteedStopLossOrderRequest),
149 TrailingStopLossOrderRequest(TrailingStopLossOrderRequest),
151}
152
153impl<'de> Deserialize<'de> for OrderRequest {
154 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
155 let value = serde_json::Value::deserialize(deserializer)?;
156 let kind = value
157 .get("type")
158 .and_then(serde_json::Value::as_str)
159 .ok_or_else(|| serde::de::Error::custom("missing OANDA type discriminator"))?;
160 match kind {
161 "MARKET" => serde_json::from_value(value)
162 .map(Self::MarketOrderRequest)
163 .map_err(serde::de::Error::custom),
164 "LIMIT" => serde_json::from_value(value)
165 .map(Self::LimitOrderRequest)
166 .map_err(serde::de::Error::custom),
167 "STOP" => serde_json::from_value(value)
168 .map(Self::StopOrderRequest)
169 .map_err(serde::de::Error::custom),
170 "MARKET_IF_TOUCHED" => serde_json::from_value(value)
171 .map(Self::MarketIfTouchedOrderRequest)
172 .map_err(serde::de::Error::custom),
173 "TAKE_PROFIT" => serde_json::from_value(value)
174 .map(Self::TakeProfitOrderRequest)
175 .map_err(serde::de::Error::custom),
176 "STOP_LOSS" => serde_json::from_value(value)
177 .map(Self::StopLossOrderRequest)
178 .map_err(serde::de::Error::custom),
179 "GUARANTEED_STOP_LOSS" => serde_json::from_value(value)
180 .map(Self::GuaranteedStopLossOrderRequest)
181 .map_err(serde::de::Error::custom),
182 "TRAILING_STOP_LOSS" => serde_json::from_value(value)
183 .map(Self::TrailingStopLossOrderRequest)
184 .map_err(serde::de::Error::custom),
185 _ => Err(serde::de::Error::custom("unsupported OANDA request type")),
186 }
187 }
188}
189
190impl Serialize for OrderRequest {
191 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
192 let (kind, mut value) = match self {
193 Self::MarketOrderRequest(body) => (
194 "MARKET",
195 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
196 ),
197 Self::LimitOrderRequest(body) => (
198 "LIMIT",
199 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
200 ),
201 Self::StopOrderRequest(body) => (
202 "STOP",
203 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
204 ),
205 Self::MarketIfTouchedOrderRequest(body) => (
206 "MARKET_IF_TOUCHED",
207 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
208 ),
209 Self::TakeProfitOrderRequest(body) => (
210 "TAKE_PROFIT",
211 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
212 ),
213 Self::StopLossOrderRequest(body) => (
214 "STOP_LOSS",
215 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
216 ),
217 Self::GuaranteedStopLossOrderRequest(body) => (
218 "GUARANTEED_STOP_LOSS",
219 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
220 ),
221 Self::TrailingStopLossOrderRequest(body) => (
222 "TRAILING_STOP_LOSS",
223 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
224 ),
225 };
226 let object = value
227 .as_object_mut()
228 .ok_or_else(|| serde::ser::Error::custom("OANDA variant must be an object"))?;
229 object.insert(
230 "type".to_owned(),
231 serde_json::Value::String(kind.to_owned()),
232 );
233 value.serialize(serializer)
234 }
235}
236
237#[derive(Debug, Clone, PartialEq)]
239#[non_exhaustive]
240#[expect(
241 clippy::large_enum_variant,
242 reason = "boxing a variant would change every caller's match; the stream already boxes the whole Transaction"
243)]
244pub enum Transaction {
245 CreateTransaction(CreateTransaction),
247 CloseTransaction(CloseTransaction),
249 ReopenTransaction(ReopenTransaction),
251 ClientConfigureTransaction(ClientConfigureTransaction),
253 ClientConfigureRejectTransaction(ClientConfigureRejectTransaction),
255 TransferFundsTransaction(TransferFundsTransaction),
257 TransferFundsRejectTransaction(TransferFundsRejectTransaction),
259 MarketOrderTransaction(MarketOrderTransaction),
261 MarketOrderRejectTransaction(MarketOrderRejectTransaction),
263 FixedPriceOrderTransaction(FixedPriceOrderTransaction),
265 LimitOrderTransaction(LimitOrderTransaction),
267 LimitOrderRejectTransaction(LimitOrderRejectTransaction),
269 StopOrderTransaction(StopOrderTransaction),
271 StopOrderRejectTransaction(StopOrderRejectTransaction),
273 MarketIfTouchedOrderTransaction(MarketIfTouchedOrderTransaction),
275 MarketIfTouchedOrderRejectTransaction(MarketIfTouchedOrderRejectTransaction),
277 TakeProfitOrderTransaction(TakeProfitOrderTransaction),
279 TakeProfitOrderRejectTransaction(TakeProfitOrderRejectTransaction),
281 StopLossOrderTransaction(StopLossOrderTransaction),
283 StopLossOrderRejectTransaction(StopLossOrderRejectTransaction),
285 GuaranteedStopLossOrderTransaction(GuaranteedStopLossOrderTransaction),
287 GuaranteedStopLossOrderRejectTransaction(GuaranteedStopLossOrderRejectTransaction),
289 TrailingStopLossOrderTransaction(TrailingStopLossOrderTransaction),
291 TrailingStopLossOrderRejectTransaction(TrailingStopLossOrderRejectTransaction),
293 OrderFillTransaction(OrderFillTransaction),
295 OrderCancelTransaction(OrderCancelTransaction),
297 OrderCancelRejectTransaction(OrderCancelRejectTransaction),
299 OrderClientExtensionsModifyTransaction(OrderClientExtensionsModifyTransaction),
301 OrderClientExtensionsModifyRejectTransaction(OrderClientExtensionsModifyRejectTransaction),
303 TradeClientExtensionsModifyTransaction(TradeClientExtensionsModifyTransaction),
305 TradeClientExtensionsModifyRejectTransaction(TradeClientExtensionsModifyRejectTransaction),
307 MarginCallEnterTransaction(MarginCallEnterTransaction),
309 MarginCallExtendTransaction(MarginCallExtendTransaction),
311 MarginCallExitTransaction(MarginCallExitTransaction),
313 DelayedTradeClosureTransaction(DelayedTradeClosureTransaction),
315 DailyFinancingTransaction(DailyFinancingTransaction),
317 DividendAdjustmentTransaction(DividendAdjustmentTransaction),
319 ResetResettablePLTransaction(ResetResettablePLTransaction),
321 Unknown {
323 kind: String,
325 raw: serde_json::Value,
327 },
328}
329
330impl<'de> Deserialize<'de> for Transaction {
331 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
332 let value = serde_json::Value::deserialize(deserializer)?;
333 let kind = value
334 .get("type")
335 .and_then(serde_json::Value::as_str)
336 .ok_or_else(|| serde::de::Error::custom("missing OANDA type discriminator"))?;
337 match kind {
338 "CREATE" => serde_json::from_value(value)
339 .map(Self::CreateTransaction)
340 .map_err(serde::de::Error::custom),
341 "CLOSE" => serde_json::from_value(value)
342 .map(Self::CloseTransaction)
343 .map_err(serde::de::Error::custom),
344 "REOPEN" => serde_json::from_value(value)
345 .map(Self::ReopenTransaction)
346 .map_err(serde::de::Error::custom),
347 "CLIENT_CONFIGURE" => serde_json::from_value(value)
348 .map(Self::ClientConfigureTransaction)
349 .map_err(serde::de::Error::custom),
350 "CLIENT_CONFIGURE_REJECT" => serde_json::from_value(value)
351 .map(Self::ClientConfigureRejectTransaction)
352 .map_err(serde::de::Error::custom),
353 "TRANSFER_FUNDS" => serde_json::from_value(value)
354 .map(Self::TransferFundsTransaction)
355 .map_err(serde::de::Error::custom),
356 "TRANSFER_FUNDS_REJECT" => serde_json::from_value(value)
357 .map(Self::TransferFundsRejectTransaction)
358 .map_err(serde::de::Error::custom),
359 "MARKET_ORDER" => serde_json::from_value(value)
360 .map(Self::MarketOrderTransaction)
361 .map_err(serde::de::Error::custom),
362 "MARKET_ORDER_REJECT" => serde_json::from_value(value)
363 .map(Self::MarketOrderRejectTransaction)
364 .map_err(serde::de::Error::custom),
365 "FIXED_PRICE_ORDER" => serde_json::from_value(value)
366 .map(Self::FixedPriceOrderTransaction)
367 .map_err(serde::de::Error::custom),
368 "LIMIT_ORDER" => serde_json::from_value(value)
369 .map(Self::LimitOrderTransaction)
370 .map_err(serde::de::Error::custom),
371 "LIMIT_ORDER_REJECT" => serde_json::from_value(value)
372 .map(Self::LimitOrderRejectTransaction)
373 .map_err(serde::de::Error::custom),
374 "STOP_ORDER" => serde_json::from_value(value)
375 .map(Self::StopOrderTransaction)
376 .map_err(serde::de::Error::custom),
377 "STOP_ORDER_REJECT" => serde_json::from_value(value)
378 .map(Self::StopOrderRejectTransaction)
379 .map_err(serde::de::Error::custom),
380 "MARKET_IF_TOUCHED_ORDER" => serde_json::from_value(value)
381 .map(Self::MarketIfTouchedOrderTransaction)
382 .map_err(serde::de::Error::custom),
383 "MARKET_IF_TOUCHED_ORDER_REJECT" => serde_json::from_value(value)
384 .map(Self::MarketIfTouchedOrderRejectTransaction)
385 .map_err(serde::de::Error::custom),
386 "TAKE_PROFIT_ORDER" => serde_json::from_value(value)
387 .map(Self::TakeProfitOrderTransaction)
388 .map_err(serde::de::Error::custom),
389 "TAKE_PROFIT_ORDER_REJECT" => serde_json::from_value(value)
390 .map(Self::TakeProfitOrderRejectTransaction)
391 .map_err(serde::de::Error::custom),
392 "STOP_LOSS_ORDER" => serde_json::from_value(value)
393 .map(Self::StopLossOrderTransaction)
394 .map_err(serde::de::Error::custom),
395 "STOP_LOSS_ORDER_REJECT" => serde_json::from_value(value)
396 .map(Self::StopLossOrderRejectTransaction)
397 .map_err(serde::de::Error::custom),
398 "GUARANTEED_STOP_LOSS_ORDER" => serde_json::from_value(value)
399 .map(Self::GuaranteedStopLossOrderTransaction)
400 .map_err(serde::de::Error::custom),
401 "GUARANTEED_STOP_LOSS_ORDER_REJECT" => serde_json::from_value(value)
402 .map(Self::GuaranteedStopLossOrderRejectTransaction)
403 .map_err(serde::de::Error::custom),
404 "TRAILING_STOP_LOSS_ORDER" => serde_json::from_value(value)
405 .map(Self::TrailingStopLossOrderTransaction)
406 .map_err(serde::de::Error::custom),
407 "TRAILING_STOP_LOSS_ORDER_REJECT" => serde_json::from_value(value)
408 .map(Self::TrailingStopLossOrderRejectTransaction)
409 .map_err(serde::de::Error::custom),
410 "ORDER_FILL" => serde_json::from_value(value)
411 .map(Self::OrderFillTransaction)
412 .map_err(serde::de::Error::custom),
413 "ORDER_CANCEL" => serde_json::from_value(value)
414 .map(Self::OrderCancelTransaction)
415 .map_err(serde::de::Error::custom),
416 "ORDER_CANCEL_REJECT" => serde_json::from_value(value)
417 .map(Self::OrderCancelRejectTransaction)
418 .map_err(serde::de::Error::custom),
419 "ORDER_CLIENT_EXTENSIONS_MODIFY" => serde_json::from_value(value)
420 .map(Self::OrderClientExtensionsModifyTransaction)
421 .map_err(serde::de::Error::custom),
422 "ORDER_CLIENT_EXTENSIONS_MODIFY_REJECT" => serde_json::from_value(value)
423 .map(Self::OrderClientExtensionsModifyRejectTransaction)
424 .map_err(serde::de::Error::custom),
425 "TRADE_CLIENT_EXTENSIONS_MODIFY" => serde_json::from_value(value)
426 .map(Self::TradeClientExtensionsModifyTransaction)
427 .map_err(serde::de::Error::custom),
428 "TRADE_CLIENT_EXTENSIONS_MODIFY_REJECT" => serde_json::from_value(value)
429 .map(Self::TradeClientExtensionsModifyRejectTransaction)
430 .map_err(serde::de::Error::custom),
431 "MARGIN_CALL_ENTER" => serde_json::from_value(value)
432 .map(Self::MarginCallEnterTransaction)
433 .map_err(serde::de::Error::custom),
434 "MARGIN_CALL_EXTEND" => serde_json::from_value(value)
435 .map(Self::MarginCallExtendTransaction)
436 .map_err(serde::de::Error::custom),
437 "MARGIN_CALL_EXIT" => serde_json::from_value(value)
438 .map(Self::MarginCallExitTransaction)
439 .map_err(serde::de::Error::custom),
440 "DELAYED_TRADE_CLOSURE" => serde_json::from_value(value)
441 .map(Self::DelayedTradeClosureTransaction)
442 .map_err(serde::de::Error::custom),
443 "DAILY_FINANCING" => serde_json::from_value(value)
444 .map(Self::DailyFinancingTransaction)
445 .map_err(serde::de::Error::custom),
446 "DIVIDEND_ADJUSTMENT" => serde_json::from_value(value)
447 .map(Self::DividendAdjustmentTransaction)
448 .map_err(serde::de::Error::custom),
449 "RESET_RESETTABLE_PL" => serde_json::from_value(value)
450 .map(Self::ResetResettablePLTransaction)
451 .map_err(serde::de::Error::custom),
452 other => Ok(Self::Unknown {
453 kind: other.to_owned(),
454 raw: value,
455 }),
456 }
457 }
458}
459
460impl Serialize for Transaction {
461 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
462 let (kind, mut value) = match self {
463 Self::CreateTransaction(body) => (
464 "CREATE",
465 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
466 ),
467 Self::CloseTransaction(body) => (
468 "CLOSE",
469 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
470 ),
471 Self::ReopenTransaction(body) => (
472 "REOPEN",
473 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
474 ),
475 Self::ClientConfigureTransaction(body) => (
476 "CLIENT_CONFIGURE",
477 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
478 ),
479 Self::ClientConfigureRejectTransaction(body) => (
480 "CLIENT_CONFIGURE_REJECT",
481 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
482 ),
483 Self::TransferFundsTransaction(body) => (
484 "TRANSFER_FUNDS",
485 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
486 ),
487 Self::TransferFundsRejectTransaction(body) => (
488 "TRANSFER_FUNDS_REJECT",
489 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
490 ),
491 Self::MarketOrderTransaction(body) => (
492 "MARKET_ORDER",
493 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
494 ),
495 Self::MarketOrderRejectTransaction(body) => (
496 "MARKET_ORDER_REJECT",
497 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
498 ),
499 Self::FixedPriceOrderTransaction(body) => (
500 "FIXED_PRICE_ORDER",
501 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
502 ),
503 Self::LimitOrderTransaction(body) => (
504 "LIMIT_ORDER",
505 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
506 ),
507 Self::LimitOrderRejectTransaction(body) => (
508 "LIMIT_ORDER_REJECT",
509 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
510 ),
511 Self::StopOrderTransaction(body) => (
512 "STOP_ORDER",
513 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
514 ),
515 Self::StopOrderRejectTransaction(body) => (
516 "STOP_ORDER_REJECT",
517 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
518 ),
519 Self::MarketIfTouchedOrderTransaction(body) => (
520 "MARKET_IF_TOUCHED_ORDER",
521 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
522 ),
523 Self::MarketIfTouchedOrderRejectTransaction(body) => (
524 "MARKET_IF_TOUCHED_ORDER_REJECT",
525 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
526 ),
527 Self::TakeProfitOrderTransaction(body) => (
528 "TAKE_PROFIT_ORDER",
529 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
530 ),
531 Self::TakeProfitOrderRejectTransaction(body) => (
532 "TAKE_PROFIT_ORDER_REJECT",
533 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
534 ),
535 Self::StopLossOrderTransaction(body) => (
536 "STOP_LOSS_ORDER",
537 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
538 ),
539 Self::StopLossOrderRejectTransaction(body) => (
540 "STOP_LOSS_ORDER_REJECT",
541 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
542 ),
543 Self::GuaranteedStopLossOrderTransaction(body) => (
544 "GUARANTEED_STOP_LOSS_ORDER",
545 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
546 ),
547 Self::GuaranteedStopLossOrderRejectTransaction(body) => (
548 "GUARANTEED_STOP_LOSS_ORDER_REJECT",
549 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
550 ),
551 Self::TrailingStopLossOrderTransaction(body) => (
552 "TRAILING_STOP_LOSS_ORDER",
553 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
554 ),
555 Self::TrailingStopLossOrderRejectTransaction(body) => (
556 "TRAILING_STOP_LOSS_ORDER_REJECT",
557 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
558 ),
559 Self::OrderFillTransaction(body) => (
560 "ORDER_FILL",
561 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
562 ),
563 Self::OrderCancelTransaction(body) => (
564 "ORDER_CANCEL",
565 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
566 ),
567 Self::OrderCancelRejectTransaction(body) => (
568 "ORDER_CANCEL_REJECT",
569 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
570 ),
571 Self::OrderClientExtensionsModifyTransaction(body) => (
572 "ORDER_CLIENT_EXTENSIONS_MODIFY",
573 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
574 ),
575 Self::OrderClientExtensionsModifyRejectTransaction(body) => (
576 "ORDER_CLIENT_EXTENSIONS_MODIFY_REJECT",
577 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
578 ),
579 Self::TradeClientExtensionsModifyTransaction(body) => (
580 "TRADE_CLIENT_EXTENSIONS_MODIFY",
581 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
582 ),
583 Self::TradeClientExtensionsModifyRejectTransaction(body) => (
584 "TRADE_CLIENT_EXTENSIONS_MODIFY_REJECT",
585 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
586 ),
587 Self::MarginCallEnterTransaction(body) => (
588 "MARGIN_CALL_ENTER",
589 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
590 ),
591 Self::MarginCallExtendTransaction(body) => (
592 "MARGIN_CALL_EXTEND",
593 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
594 ),
595 Self::MarginCallExitTransaction(body) => (
596 "MARGIN_CALL_EXIT",
597 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
598 ),
599 Self::DelayedTradeClosureTransaction(body) => (
600 "DELAYED_TRADE_CLOSURE",
601 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
602 ),
603 Self::DailyFinancingTransaction(body) => (
604 "DAILY_FINANCING",
605 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
606 ),
607 Self::DividendAdjustmentTransaction(body) => (
608 "DIVIDEND_ADJUSTMENT",
609 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
610 ),
611 Self::ResetResettablePLTransaction(body) => (
612 "RESET_RESETTABLE_PL",
613 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
614 ),
615 Self::Unknown { kind, raw } => (kind.as_str(), raw.clone()),
616 };
617 let object = value
618 .as_object_mut()
619 .ok_or_else(|| serde::ser::Error::custom("OANDA variant must be an object"))?;
620 object.insert(
621 "type".to_owned(),
622 serde_json::Value::String(kind.to_owned()),
623 );
624 value.serialize(serializer)
625 }
626}