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]
240pub enum Transaction {
241 CreateTransaction(CreateTransaction),
243 CloseTransaction(CloseTransaction),
245 ReopenTransaction(ReopenTransaction),
247 ClientConfigureTransaction(ClientConfigureTransaction),
249 ClientConfigureRejectTransaction(ClientConfigureRejectTransaction),
251 TransferFundsTransaction(TransferFundsTransaction),
253 TransferFundsRejectTransaction(TransferFundsRejectTransaction),
255 MarketOrderTransaction(MarketOrderTransaction),
257 MarketOrderRejectTransaction(MarketOrderRejectTransaction),
259 FixedPriceOrderTransaction(FixedPriceOrderTransaction),
261 LimitOrderTransaction(LimitOrderTransaction),
263 LimitOrderRejectTransaction(LimitOrderRejectTransaction),
265 StopOrderTransaction(StopOrderTransaction),
267 StopOrderRejectTransaction(StopOrderRejectTransaction),
269 MarketIfTouchedOrderTransaction(MarketIfTouchedOrderTransaction),
271 MarketIfTouchedOrderRejectTransaction(MarketIfTouchedOrderRejectTransaction),
273 TakeProfitOrderTransaction(TakeProfitOrderTransaction),
275 TakeProfitOrderRejectTransaction(TakeProfitOrderRejectTransaction),
277 StopLossOrderTransaction(StopLossOrderTransaction),
279 StopLossOrderRejectTransaction(StopLossOrderRejectTransaction),
281 GuaranteedStopLossOrderTransaction(GuaranteedStopLossOrderTransaction),
283 GuaranteedStopLossOrderRejectTransaction(GuaranteedStopLossOrderRejectTransaction),
285 TrailingStopLossOrderTransaction(TrailingStopLossOrderTransaction),
287 TrailingStopLossOrderRejectTransaction(TrailingStopLossOrderRejectTransaction),
289 OrderFillTransaction(OrderFillTransaction),
291 OrderCancelTransaction(OrderCancelTransaction),
293 OrderCancelRejectTransaction(OrderCancelRejectTransaction),
295 OrderClientExtensionsModifyTransaction(OrderClientExtensionsModifyTransaction),
297 OrderClientExtensionsModifyRejectTransaction(OrderClientExtensionsModifyRejectTransaction),
299 TradeClientExtensionsModifyTransaction(TradeClientExtensionsModifyTransaction),
301 TradeClientExtensionsModifyRejectTransaction(TradeClientExtensionsModifyRejectTransaction),
303 MarginCallEnterTransaction(MarginCallEnterTransaction),
305 MarginCallExtendTransaction(MarginCallExtendTransaction),
307 MarginCallExitTransaction(MarginCallExitTransaction),
309 DelayedTradeClosureTransaction(DelayedTradeClosureTransaction),
311 DailyFinancingTransaction(DailyFinancingTransaction),
313 DividendAdjustmentTransaction(DividendAdjustmentTransaction),
315 ResetResettablePLTransaction(ResetResettablePLTransaction),
317 Unknown {
319 kind: String,
321 raw: serde_json::Value,
323 },
324}
325
326impl<'de> Deserialize<'de> for Transaction {
327 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
328 let value = serde_json::Value::deserialize(deserializer)?;
329 let kind = value
330 .get("type")
331 .and_then(serde_json::Value::as_str)
332 .ok_or_else(|| serde::de::Error::custom("missing OANDA type discriminator"))?;
333 match kind {
334 "CREATE" => serde_json::from_value(value)
335 .map(Self::CreateTransaction)
336 .map_err(serde::de::Error::custom),
337 "CLOSE" => serde_json::from_value(value)
338 .map(Self::CloseTransaction)
339 .map_err(serde::de::Error::custom),
340 "REOPEN" => serde_json::from_value(value)
341 .map(Self::ReopenTransaction)
342 .map_err(serde::de::Error::custom),
343 "CLIENT_CONFIGURE" => serde_json::from_value(value)
344 .map(Self::ClientConfigureTransaction)
345 .map_err(serde::de::Error::custom),
346 "CLIENT_CONFIGURE_REJECT" => serde_json::from_value(value)
347 .map(Self::ClientConfigureRejectTransaction)
348 .map_err(serde::de::Error::custom),
349 "TRANSFER_FUNDS" => serde_json::from_value(value)
350 .map(Self::TransferFundsTransaction)
351 .map_err(serde::de::Error::custom),
352 "TRANSFER_FUNDS_REJECT" => serde_json::from_value(value)
353 .map(Self::TransferFundsRejectTransaction)
354 .map_err(serde::de::Error::custom),
355 "MARKET_ORDER" => serde_json::from_value(value)
356 .map(Self::MarketOrderTransaction)
357 .map_err(serde::de::Error::custom),
358 "MARKET_ORDER_REJECT" => serde_json::from_value(value)
359 .map(Self::MarketOrderRejectTransaction)
360 .map_err(serde::de::Error::custom),
361 "FIXED_PRICE_ORDER" => serde_json::from_value(value)
362 .map(Self::FixedPriceOrderTransaction)
363 .map_err(serde::de::Error::custom),
364 "LIMIT_ORDER" => serde_json::from_value(value)
365 .map(Self::LimitOrderTransaction)
366 .map_err(serde::de::Error::custom),
367 "LIMIT_ORDER_REJECT" => serde_json::from_value(value)
368 .map(Self::LimitOrderRejectTransaction)
369 .map_err(serde::de::Error::custom),
370 "STOP_ORDER" => serde_json::from_value(value)
371 .map(Self::StopOrderTransaction)
372 .map_err(serde::de::Error::custom),
373 "STOP_ORDER_REJECT" => serde_json::from_value(value)
374 .map(Self::StopOrderRejectTransaction)
375 .map_err(serde::de::Error::custom),
376 "MARKET_IF_TOUCHED_ORDER" => serde_json::from_value(value)
377 .map(Self::MarketIfTouchedOrderTransaction)
378 .map_err(serde::de::Error::custom),
379 "MARKET_IF_TOUCHED_ORDER_REJECT" => serde_json::from_value(value)
380 .map(Self::MarketIfTouchedOrderRejectTransaction)
381 .map_err(serde::de::Error::custom),
382 "TAKE_PROFIT_ORDER" => serde_json::from_value(value)
383 .map(Self::TakeProfitOrderTransaction)
384 .map_err(serde::de::Error::custom),
385 "TAKE_PROFIT_ORDER_REJECT" => serde_json::from_value(value)
386 .map(Self::TakeProfitOrderRejectTransaction)
387 .map_err(serde::de::Error::custom),
388 "STOP_LOSS_ORDER" => serde_json::from_value(value)
389 .map(Self::StopLossOrderTransaction)
390 .map_err(serde::de::Error::custom),
391 "STOP_LOSS_ORDER_REJECT" => serde_json::from_value(value)
392 .map(Self::StopLossOrderRejectTransaction)
393 .map_err(serde::de::Error::custom),
394 "GUARANTEED_STOP_LOSS_ORDER" => serde_json::from_value(value)
395 .map(Self::GuaranteedStopLossOrderTransaction)
396 .map_err(serde::de::Error::custom),
397 "GUARANTEED_STOP_LOSS_ORDER_REJECT" => serde_json::from_value(value)
398 .map(Self::GuaranteedStopLossOrderRejectTransaction)
399 .map_err(serde::de::Error::custom),
400 "TRAILING_STOP_LOSS_ORDER" => serde_json::from_value(value)
401 .map(Self::TrailingStopLossOrderTransaction)
402 .map_err(serde::de::Error::custom),
403 "TRAILING_STOP_LOSS_ORDER_REJECT" => serde_json::from_value(value)
404 .map(Self::TrailingStopLossOrderRejectTransaction)
405 .map_err(serde::de::Error::custom),
406 "ORDER_FILL" => serde_json::from_value(value)
407 .map(Self::OrderFillTransaction)
408 .map_err(serde::de::Error::custom),
409 "ORDER_CANCEL" => serde_json::from_value(value)
410 .map(Self::OrderCancelTransaction)
411 .map_err(serde::de::Error::custom),
412 "ORDER_CANCEL_REJECT" => serde_json::from_value(value)
413 .map(Self::OrderCancelRejectTransaction)
414 .map_err(serde::de::Error::custom),
415 "ORDER_CLIENT_EXTENSIONS_MODIFY" => serde_json::from_value(value)
416 .map(Self::OrderClientExtensionsModifyTransaction)
417 .map_err(serde::de::Error::custom),
418 "ORDER_CLIENT_EXTENSIONS_MODIFY_REJECT" => serde_json::from_value(value)
419 .map(Self::OrderClientExtensionsModifyRejectTransaction)
420 .map_err(serde::de::Error::custom),
421 "TRADE_CLIENT_EXTENSIONS_MODIFY" => serde_json::from_value(value)
422 .map(Self::TradeClientExtensionsModifyTransaction)
423 .map_err(serde::de::Error::custom),
424 "TRADE_CLIENT_EXTENSIONS_MODIFY_REJECT" => serde_json::from_value(value)
425 .map(Self::TradeClientExtensionsModifyRejectTransaction)
426 .map_err(serde::de::Error::custom),
427 "MARGIN_CALL_ENTER" => serde_json::from_value(value)
428 .map(Self::MarginCallEnterTransaction)
429 .map_err(serde::de::Error::custom),
430 "MARGIN_CALL_EXTEND" => serde_json::from_value(value)
431 .map(Self::MarginCallExtendTransaction)
432 .map_err(serde::de::Error::custom),
433 "MARGIN_CALL_EXIT" => serde_json::from_value(value)
434 .map(Self::MarginCallExitTransaction)
435 .map_err(serde::de::Error::custom),
436 "DELAYED_TRADE_CLOSURE" => serde_json::from_value(value)
437 .map(Self::DelayedTradeClosureTransaction)
438 .map_err(serde::de::Error::custom),
439 "DAILY_FINANCING" => serde_json::from_value(value)
440 .map(Self::DailyFinancingTransaction)
441 .map_err(serde::de::Error::custom),
442 "DIVIDEND_ADJUSTMENT" => serde_json::from_value(value)
443 .map(Self::DividendAdjustmentTransaction)
444 .map_err(serde::de::Error::custom),
445 "RESET_RESETTABLE_PL" => serde_json::from_value(value)
446 .map(Self::ResetResettablePLTransaction)
447 .map_err(serde::de::Error::custom),
448 other => Ok(Self::Unknown {
449 kind: other.to_owned(),
450 raw: value,
451 }),
452 }
453 }
454}
455
456impl Serialize for Transaction {
457 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
458 let (kind, mut value) = match self {
459 Self::CreateTransaction(body) => (
460 "CREATE",
461 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
462 ),
463 Self::CloseTransaction(body) => (
464 "CLOSE",
465 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
466 ),
467 Self::ReopenTransaction(body) => (
468 "REOPEN",
469 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
470 ),
471 Self::ClientConfigureTransaction(body) => (
472 "CLIENT_CONFIGURE",
473 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
474 ),
475 Self::ClientConfigureRejectTransaction(body) => (
476 "CLIENT_CONFIGURE_REJECT",
477 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
478 ),
479 Self::TransferFundsTransaction(body) => (
480 "TRANSFER_FUNDS",
481 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
482 ),
483 Self::TransferFundsRejectTransaction(body) => (
484 "TRANSFER_FUNDS_REJECT",
485 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
486 ),
487 Self::MarketOrderTransaction(body) => (
488 "MARKET_ORDER",
489 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
490 ),
491 Self::MarketOrderRejectTransaction(body) => (
492 "MARKET_ORDER_REJECT",
493 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
494 ),
495 Self::FixedPriceOrderTransaction(body) => (
496 "FIXED_PRICE_ORDER",
497 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
498 ),
499 Self::LimitOrderTransaction(body) => (
500 "LIMIT_ORDER",
501 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
502 ),
503 Self::LimitOrderRejectTransaction(body) => (
504 "LIMIT_ORDER_REJECT",
505 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
506 ),
507 Self::StopOrderTransaction(body) => (
508 "STOP_ORDER",
509 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
510 ),
511 Self::StopOrderRejectTransaction(body) => (
512 "STOP_ORDER_REJECT",
513 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
514 ),
515 Self::MarketIfTouchedOrderTransaction(body) => (
516 "MARKET_IF_TOUCHED_ORDER",
517 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
518 ),
519 Self::MarketIfTouchedOrderRejectTransaction(body) => (
520 "MARKET_IF_TOUCHED_ORDER_REJECT",
521 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
522 ),
523 Self::TakeProfitOrderTransaction(body) => (
524 "TAKE_PROFIT_ORDER",
525 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
526 ),
527 Self::TakeProfitOrderRejectTransaction(body) => (
528 "TAKE_PROFIT_ORDER_REJECT",
529 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
530 ),
531 Self::StopLossOrderTransaction(body) => (
532 "STOP_LOSS_ORDER",
533 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
534 ),
535 Self::StopLossOrderRejectTransaction(body) => (
536 "STOP_LOSS_ORDER_REJECT",
537 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
538 ),
539 Self::GuaranteedStopLossOrderTransaction(body) => (
540 "GUARANTEED_STOP_LOSS_ORDER",
541 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
542 ),
543 Self::GuaranteedStopLossOrderRejectTransaction(body) => (
544 "GUARANTEED_STOP_LOSS_ORDER_REJECT",
545 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
546 ),
547 Self::TrailingStopLossOrderTransaction(body) => (
548 "TRAILING_STOP_LOSS_ORDER",
549 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
550 ),
551 Self::TrailingStopLossOrderRejectTransaction(body) => (
552 "TRAILING_STOP_LOSS_ORDER_REJECT",
553 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
554 ),
555 Self::OrderFillTransaction(body) => (
556 "ORDER_FILL",
557 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
558 ),
559 Self::OrderCancelTransaction(body) => (
560 "ORDER_CANCEL",
561 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
562 ),
563 Self::OrderCancelRejectTransaction(body) => (
564 "ORDER_CANCEL_REJECT",
565 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
566 ),
567 Self::OrderClientExtensionsModifyTransaction(body) => (
568 "ORDER_CLIENT_EXTENSIONS_MODIFY",
569 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
570 ),
571 Self::OrderClientExtensionsModifyRejectTransaction(body) => (
572 "ORDER_CLIENT_EXTENSIONS_MODIFY_REJECT",
573 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
574 ),
575 Self::TradeClientExtensionsModifyTransaction(body) => (
576 "TRADE_CLIENT_EXTENSIONS_MODIFY",
577 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
578 ),
579 Self::TradeClientExtensionsModifyRejectTransaction(body) => (
580 "TRADE_CLIENT_EXTENSIONS_MODIFY_REJECT",
581 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
582 ),
583 Self::MarginCallEnterTransaction(body) => (
584 "MARGIN_CALL_ENTER",
585 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
586 ),
587 Self::MarginCallExtendTransaction(body) => (
588 "MARGIN_CALL_EXTEND",
589 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
590 ),
591 Self::MarginCallExitTransaction(body) => (
592 "MARGIN_CALL_EXIT",
593 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
594 ),
595 Self::DelayedTradeClosureTransaction(body) => (
596 "DELAYED_TRADE_CLOSURE",
597 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
598 ),
599 Self::DailyFinancingTransaction(body) => (
600 "DAILY_FINANCING",
601 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
602 ),
603 Self::DividendAdjustmentTransaction(body) => (
604 "DIVIDEND_ADJUSTMENT",
605 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
606 ),
607 Self::ResetResettablePLTransaction(body) => (
608 "RESET_RESETTABLE_PL",
609 serde_json::to_value(body).map_err(serde::ser::Error::custom)?,
610 ),
611 Self::Unknown { kind, raw } => (kind.as_str(), raw.clone()),
612 };
613 let object = value
614 .as_object_mut()
615 .ok_or_else(|| serde::ser::Error::custom("OANDA variant must be an object"))?;
616 object.insert(
617 "type".to_owned(),
618 serde_json::Value::String(kind.to_owned()),
619 );
620 value.serialize(serializer)
621 }
622}