1use std::{
28 cell::{Ref, RefMut},
29 fmt::{Debug, Display},
30 ops::{Deref, DerefMut},
31};
32
33use nautilus_model::{accounts::AccountAny, orders::OrderAny, position::Position};
34
35pub struct AccountRef<'a>(Ref<'a, AccountAny>);
46
47impl<'a> AccountRef<'a> {
48 #[must_use]
50 pub fn new(inner: Ref<'a, AccountAny>) -> Self {
51 Self(inner)
52 }
53
54 #[must_use]
59 pub fn cloned(&self) -> AccountAny {
60 (*self.0).clone()
61 }
62}
63
64impl Deref for AccountRef<'_> {
65 type Target = AccountAny;
66
67 fn deref(&self) -> &Self::Target {
68 &self.0
69 }
70}
71
72impl AsRef<AccountAny> for AccountRef<'_> {
73 fn as_ref(&self) -> &AccountAny {
74 &self.0
75 }
76}
77
78impl<'a> From<Ref<'a, AccountAny>> for AccountRef<'a> {
79 fn from(inner: Ref<'a, AccountAny>) -> Self {
80 Self(inner)
81 }
82}
83
84impl PartialEq<AccountAny> for AccountRef<'_> {
85 fn eq(&self, other: &AccountAny) -> bool {
86 &**self == other
87 }
88}
89
90impl PartialEq<&AccountAny> for AccountRef<'_> {
91 fn eq(&self, other: &&AccountAny) -> bool {
92 &**self == *other
93 }
94}
95
96impl Debug for AccountRef<'_> {
97 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
98 Debug::fmt(&**self, f)
99 }
100}
101
102pub struct AccountRefMut<'a>(RefMut<'a, AccountAny>);
109
110impl<'a> AccountRefMut<'a> {
111 #[must_use]
113 pub fn new(inner: RefMut<'a, AccountAny>) -> Self {
114 Self(inner)
115 }
116
117 #[must_use]
119 pub fn cloned(&self) -> AccountAny {
120 (*self.0).clone()
121 }
122}
123
124impl Deref for AccountRefMut<'_> {
125 type Target = AccountAny;
126
127 fn deref(&self) -> &Self::Target {
128 &self.0
129 }
130}
131
132impl DerefMut for AccountRefMut<'_> {
133 fn deref_mut(&mut self) -> &mut Self::Target {
134 &mut self.0
135 }
136}
137
138impl AsRef<AccountAny> for AccountRefMut<'_> {
139 fn as_ref(&self) -> &AccountAny {
140 &self.0
141 }
142}
143
144impl AsMut<AccountAny> for AccountRefMut<'_> {
145 fn as_mut(&mut self) -> &mut AccountAny {
146 &mut self.0
147 }
148}
149
150impl<'a> From<RefMut<'a, AccountAny>> for AccountRefMut<'a> {
151 fn from(inner: RefMut<'a, AccountAny>) -> Self {
152 Self(inner)
153 }
154}
155
156impl PartialEq<AccountAny> for AccountRefMut<'_> {
157 fn eq(&self, other: &AccountAny) -> bool {
158 &**self == other
159 }
160}
161
162impl PartialEq<&AccountAny> for AccountRefMut<'_> {
163 fn eq(&self, other: &&AccountAny) -> bool {
164 &**self == *other
165 }
166}
167
168impl Debug for AccountRefMut<'_> {
169 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
170 Debug::fmt(&**self, f)
171 }
172}
173
174pub struct OrderRef<'a>(Ref<'a, OrderAny>);
185
186impl<'a> OrderRef<'a> {
187 #[must_use]
189 pub fn new(inner: Ref<'a, OrderAny>) -> Self {
190 Self(inner)
191 }
192
193 #[must_use]
198 pub fn cloned(&self) -> OrderAny {
199 (*self.0).clone()
200 }
201}
202
203impl Deref for OrderRef<'_> {
204 type Target = OrderAny;
205
206 fn deref(&self) -> &Self::Target {
207 &self.0
208 }
209}
210
211impl AsRef<OrderAny> for OrderRef<'_> {
212 fn as_ref(&self) -> &OrderAny {
213 &self.0
214 }
215}
216
217impl<'a> From<Ref<'a, OrderAny>> for OrderRef<'a> {
218 fn from(inner: Ref<'a, OrderAny>) -> Self {
219 Self(inner)
220 }
221}
222
223impl PartialEq for OrderRef<'_> {
224 fn eq(&self, other: &Self) -> bool {
225 **self == **other
226 }
227}
228
229impl PartialEq<OrderAny> for OrderRef<'_> {
230 fn eq(&self, other: &OrderAny) -> bool {
231 &**self == other
232 }
233}
234
235impl PartialEq<&OrderAny> for OrderRef<'_> {
236 fn eq(&self, other: &&OrderAny) -> bool {
237 &**self == *other
238 }
239}
240
241impl Display for OrderRef<'_> {
242 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
243 Display::fmt(&**self, f)
244 }
245}
246
247impl Debug for OrderRef<'_> {
248 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
249 Debug::fmt(&**self, f)
250 }
251}
252
253pub struct OrderRefMut<'a>(RefMut<'a, OrderAny>);
260
261impl<'a> OrderRefMut<'a> {
262 #[must_use]
264 pub fn new(inner: RefMut<'a, OrderAny>) -> Self {
265 Self(inner)
266 }
267
268 #[must_use]
270 pub fn cloned(&self) -> OrderAny {
271 (*self.0).clone()
272 }
273}
274
275impl Deref for OrderRefMut<'_> {
276 type Target = OrderAny;
277
278 fn deref(&self) -> &Self::Target {
279 &self.0
280 }
281}
282
283impl DerefMut for OrderRefMut<'_> {
284 fn deref_mut(&mut self) -> &mut Self::Target {
285 &mut self.0
286 }
287}
288
289impl AsRef<OrderAny> for OrderRefMut<'_> {
290 fn as_ref(&self) -> &OrderAny {
291 &self.0
292 }
293}
294
295impl AsMut<OrderAny> for OrderRefMut<'_> {
296 fn as_mut(&mut self) -> &mut OrderAny {
297 &mut self.0
298 }
299}
300
301impl<'a> From<RefMut<'a, OrderAny>> for OrderRefMut<'a> {
302 fn from(inner: RefMut<'a, OrderAny>) -> Self {
303 Self(inner)
304 }
305}
306
307impl PartialEq<OrderAny> for OrderRefMut<'_> {
308 fn eq(&self, other: &OrderAny) -> bool {
309 &**self == other
310 }
311}
312
313impl PartialEq<&OrderAny> for OrderRefMut<'_> {
314 fn eq(&self, other: &&OrderAny) -> bool {
315 &**self == *other
316 }
317}
318
319impl Display for OrderRefMut<'_> {
320 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
321 Display::fmt(&**self, f)
322 }
323}
324
325impl Debug for OrderRefMut<'_> {
326 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
327 Debug::fmt(&**self, f)
328 }
329}
330
331pub struct PositionRef<'a>(Ref<'a, Position>);
342
343impl<'a> PositionRef<'a> {
344 #[must_use]
346 pub fn new(inner: Ref<'a, Position>) -> Self {
347 Self(inner)
348 }
349
350 #[must_use]
355 pub fn cloned(&self) -> Position {
356 (*self.0).clone()
357 }
358}
359
360impl Deref for PositionRef<'_> {
361 type Target = Position;
362
363 fn deref(&self) -> &Self::Target {
364 &self.0
365 }
366}
367
368impl AsRef<Position> for PositionRef<'_> {
369 fn as_ref(&self) -> &Position {
370 &self.0
371 }
372}
373
374impl<'a> From<Ref<'a, Position>> for PositionRef<'a> {
375 fn from(inner: Ref<'a, Position>) -> Self {
376 Self(inner)
377 }
378}
379
380impl PartialEq for PositionRef<'_> {
381 fn eq(&self, other: &Self) -> bool {
382 **self == **other
383 }
384}
385
386impl PartialEq<Position> for PositionRef<'_> {
387 fn eq(&self, other: &Position) -> bool {
388 &**self == other
389 }
390}
391
392impl PartialEq<&Position> for PositionRef<'_> {
393 fn eq(&self, other: &&Position) -> bool {
394 &**self == *other
395 }
396}
397
398impl Display for PositionRef<'_> {
399 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
400 Display::fmt(&**self, f)
401 }
402}
403
404impl Debug for PositionRef<'_> {
405 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
406 Debug::fmt(&**self, f)
407 }
408}
409
410pub struct PositionRefMut<'a>(RefMut<'a, Position>);
417
418impl<'a> PositionRefMut<'a> {
419 #[must_use]
421 pub fn new(inner: RefMut<'a, Position>) -> Self {
422 Self(inner)
423 }
424
425 #[must_use]
427 pub fn cloned(&self) -> Position {
428 (*self.0).clone()
429 }
430}
431
432impl Deref for PositionRefMut<'_> {
433 type Target = Position;
434
435 fn deref(&self) -> &Self::Target {
436 &self.0
437 }
438}
439
440impl DerefMut for PositionRefMut<'_> {
441 fn deref_mut(&mut self) -> &mut Self::Target {
442 &mut self.0
443 }
444}
445
446impl AsRef<Position> for PositionRefMut<'_> {
447 fn as_ref(&self) -> &Position {
448 &self.0
449 }
450}
451
452impl AsMut<Position> for PositionRefMut<'_> {
453 fn as_mut(&mut self) -> &mut Position {
454 &mut self.0
455 }
456}
457
458impl<'a> From<RefMut<'a, Position>> for PositionRefMut<'a> {
459 fn from(inner: RefMut<'a, Position>) -> Self {
460 Self(inner)
461 }
462}
463
464impl PartialEq<Position> for PositionRefMut<'_> {
465 fn eq(&self, other: &Position) -> bool {
466 &**self == other
467 }
468}
469
470impl PartialEq<&Position> for PositionRefMut<'_> {
471 fn eq(&self, other: &&Position) -> bool {
472 &**self == *other
473 }
474}
475
476impl Display for PositionRefMut<'_> {
477 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
478 Display::fmt(&**self, f)
479 }
480}
481
482impl Debug for PositionRefMut<'_> {
483 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
484 Debug::fmt(&**self, f)
485 }
486}
487
488#[cfg(test)]
489mod tests {
490 use std::{cell::RefCell, rc::Rc};
491
492 use nautilus_model::{
493 accounts::{Account, CashAccount, stubs::cash_account},
494 enums::{AccountType, OrderSide, OrderType},
495 events::{AccountState, account::stubs::cash_account_state},
496 instruments::{CurrencyPair, stubs::*},
497 orders::{Order, builder::OrderTestBuilder},
498 stubs::{stub_position_long, stub_position_short},
499 types::{Price, Quantity},
500 };
501 use rstest::rstest;
502
503 use super::*;
504
505 fn make_order(audusd_sim: &CurrencyPair) -> OrderAny {
506 OrderTestBuilder::new(OrderType::Limit)
507 .instrument_id(audusd_sim.id)
508 .side(OrderSide::Buy)
509 .price(Price::from("1.00000"))
510 .quantity(Quantity::from(100_000))
511 .build()
512 }
513
514 fn make_account(state: AccountState) -> AccountAny {
515 AccountAny::Cash(CashAccount::new(state, true, false))
516 }
517
518 #[rstest]
519 fn test_account_ref_partial_eq_against_owned(cash_account_state: AccountState) {
520 let account = make_account(cash_account_state);
521 let cell = Rc::new(RefCell::new(account.clone()));
522 let account_ref = AccountRef::from(cell.borrow());
523
524 assert_eq!(account_ref, account);
525 assert_eq!(account_ref, &account);
526 }
527
528 #[rstest]
529 fn test_account_ref_debug_matches_inner(cash_account_state: AccountState) {
530 let account = make_account(cash_account_state);
531 let cell = Rc::new(RefCell::new(account.clone()));
532 let account_ref = AccountRef::from(cell.borrow());
533
534 assert_eq!(format!("{account_ref:?}"), format!("{account:?}"));
535 }
536
537 #[rstest]
538 fn test_account_ref_cloned_is_independent(cash_account_state: AccountState) {
539 let cell = Rc::new(RefCell::new(make_account(cash_account_state)));
540 let snapshot = AccountRef::from(cell.borrow()).cloned();
541
542 assert_eq!(snapshot, *cell.borrow());
543 }
544
545 #[rstest]
546 fn test_account_ref_deref_method_call(cash_account: CashAccount) {
547 let account = AccountAny::Cash(cash_account);
548 let cell = Rc::new(RefCell::new(account.clone()));
549 let account_ref = AccountRef::from(cell.borrow());
550
551 assert_eq!(account_ref.id(), account.id());
553 assert_eq!(account_ref.account_type(), AccountType::Cash);
554 }
555
556 #[rstest]
557 fn test_account_ref_mut_writes_through_deref_mut(cash_account_state: AccountState) {
558 let cell = Rc::new(RefCell::new(make_account(cash_account_state.clone())));
559 let mut account_mut = AccountRefMut::from(cell.borrow_mut());
560
561 account_mut.apply(cash_account_state).unwrap();
563 let event_count = account_mut.events().len();
564 drop(account_mut);
565
566 assert_eq!(cell.borrow().events().len(), event_count);
567 }
568
569 #[rstest]
570 fn test_account_ref_mut_partial_eq_against_owned(cash_account_state: AccountState) {
571 let account = make_account(cash_account_state);
572 let cell = Rc::new(RefCell::new(account.clone()));
573 let account_mut = AccountRefMut::from(cell.borrow_mut());
574
575 assert_eq!(account_mut, account);
576 assert_eq!(account_mut, &account);
577 }
578
579 #[rstest]
580 fn test_order_ref_partial_eq_against_owned(audusd_sim: CurrencyPair) {
581 let order = make_order(&audusd_sim);
582 let cell = Rc::new(RefCell::new(order.clone()));
583 let order_ref = OrderRef::from(cell.borrow());
584
585 assert_eq!(order_ref, order);
586 assert_eq!(order_ref, &order);
587 }
588
589 #[rstest]
590 fn test_order_ref_display_matches_inner(audusd_sim: CurrencyPair) {
591 let order = make_order(&audusd_sim);
592 let cell = Rc::new(RefCell::new(order.clone()));
593 let order_ref = OrderRef::from(cell.borrow());
594
595 assert_eq!(format!("{order_ref}"), format!("{order}"));
596 assert_eq!(format!("{order_ref:?}"), format!("{order:?}"));
597 }
598
599 #[rstest]
600 fn test_order_ref_cloned_is_independent(audusd_sim: CurrencyPair) {
601 let cell = Rc::new(RefCell::new(make_order(&audusd_sim)));
602 let snapshot = OrderRef::from(cell.borrow()).cloned();
603 let original_qty = snapshot.quantity();
604
605 cell.borrow_mut().set_quantity(Quantity::from(1));
607
608 assert_eq!(snapshot.quantity(), original_qty);
609 assert_eq!(cell.borrow().quantity(), Quantity::from(1));
610 }
611
612 #[rstest]
613 fn test_order_ref_deref_method_call(audusd_sim: CurrencyPair) {
614 let order = make_order(&audusd_sim);
615 let cell = Rc::new(RefCell::new(order.clone()));
616 let order_ref = OrderRef::from(cell.borrow());
617
618 assert_eq!(order_ref.client_order_id(), order.client_order_id());
620 assert_eq!(order_ref.quantity(), order.quantity());
621 }
622
623 #[rstest]
624 fn test_order_ref_mut_writes_through_deref_mut(audusd_sim: CurrencyPair) {
625 let cell = Rc::new(RefCell::new(make_order(&audusd_sim)));
626 let mut order_mut = OrderRefMut::from(cell.borrow_mut());
627
628 order_mut.set_quantity(Quantity::from(7));
629 drop(order_mut);
630
631 assert_eq!(cell.borrow().quantity(), Quantity::from(7));
632 }
633
634 #[rstest]
635 fn test_order_ref_mut_partial_eq_against_owned(audusd_sim: CurrencyPair) {
636 let order = make_order(&audusd_sim);
637 let cell = Rc::new(RefCell::new(order.clone()));
638 let order_mut = OrderRefMut::from(cell.borrow_mut());
639
640 assert_eq!(order_mut, order);
641 assert_eq!(order_mut, &order);
642 }
643
644 #[rstest]
645 fn test_position_ref_partial_eq_against_owned(stub_position_long: Position) {
646 let cell = Rc::new(RefCell::new(stub_position_long.clone()));
647 let position_ref = PositionRef::from(cell.borrow());
648
649 assert_eq!(position_ref, stub_position_long);
650 assert_eq!(position_ref, &stub_position_long);
651 }
652
653 #[rstest]
654 fn test_position_ref_display_matches_inner(stub_position_long: Position) {
655 let cell = Rc::new(RefCell::new(stub_position_long.clone()));
656 let position_ref = PositionRef::from(cell.borrow());
657
658 assert_eq!(format!("{position_ref}"), format!("{stub_position_long}"));
659 assert_eq!(
660 format!("{position_ref:?}"),
661 format!("{stub_position_long:?}")
662 );
663 }
664
665 #[rstest]
666 fn test_position_ref_cloned_is_independent(stub_position_short: Position) {
667 let cell = Rc::new(RefCell::new(stub_position_short));
668 let snapshot = PositionRef::from(cell.borrow()).cloned();
669 let original_qty = snapshot.quantity;
670
671 cell.borrow_mut().quantity = Quantity::from(1);
672
673 assert_eq!(snapshot.quantity, original_qty);
674 assert_eq!(cell.borrow().quantity, Quantity::from(1));
675 }
676
677 #[rstest]
678 fn test_position_ref_deref_method_call(stub_position_long: Position) {
679 let cell = Rc::new(RefCell::new(stub_position_long.clone()));
680 let position_ref = PositionRef::from(cell.borrow());
681
682 assert_eq!(position_ref.id, stub_position_long.id);
684 assert_eq!(position_ref.quantity, stub_position_long.quantity);
685 }
686
687 #[rstest]
688 fn test_position_ref_mut_writes_through_deref_mut(stub_position_long: Position) {
689 let cell = Rc::new(RefCell::new(stub_position_long));
690 let mut position_mut = PositionRefMut::from(cell.borrow_mut());
691
692 position_mut.quantity = Quantity::from(7);
693 drop(position_mut);
694
695 assert_eq!(cell.borrow().quantity, Quantity::from(7));
696 }
697
698 #[rstest]
699 fn test_position_ref_mut_partial_eq_against_owned(stub_position_long: Position) {
700 let cell = Rc::new(RefCell::new(stub_position_long.clone()));
701 let position_mut = PositionRefMut::from(cell.borrow_mut());
702
703 assert_eq!(position_mut, stub_position_long);
704 assert_eq!(position_mut, &stub_position_long);
705 }
706}