1#![allow(clippy::new_without_default)]
3#![allow(clippy::needless_pass_by_value)]
4#![allow(clippy::too_many_arguments)]
5#![allow(unused_imports)]
6
7use fixer::message::Message;
8use fixer::fix_string::FIXString;
9use fixer::errors::MessageRejectErrorEnum;
10use fixer::session::session_id::SessionID;
11
12use rust_decimal::Decimal;
13
14
15use jiff::Timestamp;
16
17use crate::field;
18use crate::tag;
19
20pub struct Allocation {
22 pub message: Message,
23}
24
25impl Allocation {
26 pub fn new(alloc_id: field::AllocIDField, alloc_trans_type: field::AllocTransTypeField, side: field::SideField, symbol: field::SymbolField, shares: field::SharesField, avg_px: field::AvgPxField, trade_date: field::TradeDateField) -> Self {
28 let mut msg = Message::new();
29 msg.header.set_field(tag::MSG_TYPE, FIXString::from("J".to_string()));
30
31 msg.body.set_field(tag::ALLOC_ID, alloc_id.0);
32
33 msg.body.set_field(tag::ALLOC_TRANS_TYPE, alloc_trans_type.0);
34
35 msg.body.set_field(tag::SIDE, side.0);
36
37 msg.body.set_field(tag::SYMBOL, symbol.0);
38
39 msg.body.set_field(tag::SHARES, shares.0);
40
41 msg.body.set_field(tag::AVG_PX, avg_px.0);
42
43 msg.body.set_field(tag::TRADE_DATE, trade_date.0);
44
45 Self { message: msg }
46 }
47
48 pub fn from_message(msg: Message) -> Self {
50 Self { message: msg }
51 }
52
53 pub fn to_message(self) -> Message {
55 self.message
56 }
57
58
59
60
61 pub fn set_accrued_interest_rate(&mut self, val: Decimal, scale: i32) {
63 self.message.body.set_field(tag::ACCRUED_INTEREST_RATE, fixer::fix_decimal::FIXDecimal { decimal: val, scale });
64 }
65
66 pub fn get_accrued_interest_rate(&self) -> Result<Decimal, MessageRejectErrorEnum> {
68 let mut fld = field::AccruedInterestRateField::new(Decimal::ZERO, 0);
69 self.message.body.get_field(tag::ACCRUED_INTEREST_RATE, &mut fld.0)?;
70 Ok(fld.value())
71 }
72
73
74 pub fn has_accrued_interest_rate(&self) -> bool {
76 self.message.body.has(tag::ACCRUED_INTEREST_RATE)
77 }
78
79
80
81
82 pub fn set_alloc_id(&mut self, v: String) {
84 self.message.body.set_field(tag::ALLOC_ID, FIXString::from(v));
85 }
86
87 pub fn get_alloc_id(&self) -> Result<String, MessageRejectErrorEnum> {
89 let mut fld = field::AllocIDField::new(String::new());
90 self.message.body.get_field(tag::ALLOC_ID, &mut fld.0)?;
91 Ok(fld.value().to_string())
92 }
93
94
95 pub fn has_alloc_id(&self) -> bool {
97 self.message.body.has(tag::ALLOC_ID)
98 }
99
100
101
102
103 pub fn set_alloc_link_id(&mut self, v: String) {
105 self.message.body.set_field(tag::ALLOC_LINK_ID, FIXString::from(v));
106 }
107
108 pub fn get_alloc_link_id(&self) -> Result<String, MessageRejectErrorEnum> {
110 let mut fld = field::AllocLinkIDField::new(String::new());
111 self.message.body.get_field(tag::ALLOC_LINK_ID, &mut fld.0)?;
112 Ok(fld.value().to_string())
113 }
114
115
116 pub fn has_alloc_link_id(&self) -> bool {
118 self.message.body.has(tag::ALLOC_LINK_ID)
119 }
120
121
122
123
124 pub fn set_alloc_link_type(&mut self, v: isize) {
126 self.message.body.set_field(tag::ALLOC_LINK_TYPE, fixer::fix_int::FIXInt::from(v));
127 }
128
129 pub fn get_alloc_link_type(&self) -> Result<isize, MessageRejectErrorEnum> {
131 let mut fld = field::AllocLinkTypeField::new(0);
132 self.message.body.get_field(tag::ALLOC_LINK_TYPE, &mut fld.0)?;
133 Ok(fld.value())
134 }
135
136
137 pub fn has_alloc_link_type(&self) -> bool {
139 self.message.body.has(tag::ALLOC_LINK_TYPE)
140 }
141
142
143
144
145 pub fn set_alloc_trans_type(&mut self, v: String) {
147 self.message.body.set_field(tag::ALLOC_TRANS_TYPE, FIXString::from(v));
148 }
149
150 pub fn get_alloc_trans_type(&self) -> Result<String, MessageRejectErrorEnum> {
152 let mut fld = field::AllocTransTypeField::new(String::new());
153 self.message.body.get_field(tag::ALLOC_TRANS_TYPE, &mut fld.0)?;
154 Ok(fld.value().to_string())
155 }
156
157
158 pub fn has_alloc_trans_type(&self) -> bool {
160 self.message.body.has(tag::ALLOC_TRANS_TYPE)
161 }
162
163
164
165
166 pub fn set_avg_prx_precision(&mut self, v: isize) {
168 self.message.body.set_field(tag::AVG_PRX_PRECISION, fixer::fix_int::FIXInt::from(v));
169 }
170
171 pub fn get_avg_prx_precision(&self) -> Result<isize, MessageRejectErrorEnum> {
173 let mut fld = field::AvgPrxPrecisionField::new(0);
174 self.message.body.get_field(tag::AVG_PRX_PRECISION, &mut fld.0)?;
175 Ok(fld.value())
176 }
177
178
179 pub fn has_avg_prx_precision(&self) -> bool {
181 self.message.body.has(tag::AVG_PRX_PRECISION)
182 }
183
184
185
186
187 pub fn set_avg_px(&mut self, val: Decimal, scale: i32) {
189 self.message.body.set_field(tag::AVG_PX, fixer::fix_decimal::FIXDecimal { decimal: val, scale });
190 }
191
192 pub fn get_avg_px(&self) -> Result<Decimal, MessageRejectErrorEnum> {
194 let mut fld = field::AvgPxField::new(Decimal::ZERO, 0);
195 self.message.body.get_field(tag::AVG_PX, &mut fld.0)?;
196 Ok(fld.value())
197 }
198
199
200 pub fn has_avg_px(&self) -> bool {
202 self.message.body.has(tag::AVG_PX)
203 }
204
205
206
207
208 pub fn set_currency(&mut self, v: String) {
210 self.message.body.set_field(tag::CURRENCY, FIXString::from(v));
211 }
212
213 pub fn get_currency(&self) -> Result<String, MessageRejectErrorEnum> {
215 let mut fld = field::CurrencyField::new(String::new());
216 self.message.body.get_field(tag::CURRENCY, &mut fld.0)?;
217 Ok(fld.value().to_string())
218 }
219
220
221 pub fn has_currency(&self) -> bool {
223 self.message.body.has(tag::CURRENCY)
224 }
225
226
227
228
229 pub fn set_fut_sett_date(&mut self, v: String) {
231 self.message.body.set_field(tag::FUT_SETT_DATE, FIXString::from(v));
232 }
233
234 pub fn get_fut_sett_date(&self) -> Result<String, MessageRejectErrorEnum> {
236 let mut fld = field::FutSettDateField::new(String::new());
237 self.message.body.get_field(tag::FUT_SETT_DATE, &mut fld.0)?;
238 Ok(fld.value().to_string())
239 }
240
241
242 pub fn has_fut_sett_date(&self) -> bool {
244 self.message.body.has(tag::FUT_SETT_DATE)
245 }
246
247
248
249
250 pub fn set_id_source(&mut self, v: String) {
252 self.message.body.set_field(tag::ID_SOURCE, FIXString::from(v));
253 }
254
255 pub fn get_id_source(&self) -> Result<String, MessageRejectErrorEnum> {
257 let mut fld = field::IDSourceField::new(String::new());
258 self.message.body.get_field(tag::ID_SOURCE, &mut fld.0)?;
259 Ok(fld.value().to_string())
260 }
261
262
263 pub fn has_id_source(&self) -> bool {
265 self.message.body.has(tag::ID_SOURCE)
266 }
267
268
269
270
271 pub fn set_issuer(&mut self, v: String) {
273 self.message.body.set_field(tag::ISSUER, FIXString::from(v));
274 }
275
276 pub fn get_issuer(&self) -> Result<String, MessageRejectErrorEnum> {
278 let mut fld = field::IssuerField::new(String::new());
279 self.message.body.get_field(tag::ISSUER, &mut fld.0)?;
280 Ok(fld.value().to_string())
281 }
282
283
284 pub fn has_issuer(&self) -> bool {
286 self.message.body.has(tag::ISSUER)
287 }
288
289
290
291
292 pub fn set_last_mkt(&mut self, v: String) {
294 self.message.body.set_field(tag::LAST_MKT, FIXString::from(v));
295 }
296
297 pub fn get_last_mkt(&self) -> Result<String, MessageRejectErrorEnum> {
299 let mut fld = field::LastMktField::new(String::new());
300 self.message.body.get_field(tag::LAST_MKT, &mut fld.0)?;
301 Ok(fld.value().to_string())
302 }
303
304
305 pub fn has_last_mkt(&self) -> bool {
307 self.message.body.has(tag::LAST_MKT)
308 }
309
310
311
312
313 pub fn set_maturity_day(&mut self, v: isize) {
315 self.message.body.set_field(tag::MATURITY_DAY, fixer::fix_int::FIXInt::from(v));
316 }
317
318 pub fn get_maturity_day(&self) -> Result<isize, MessageRejectErrorEnum> {
320 let mut fld = field::MaturityDayField::new(0);
321 self.message.body.get_field(tag::MATURITY_DAY, &mut fld.0)?;
322 Ok(fld.value())
323 }
324
325
326 pub fn has_maturity_day(&self) -> bool {
328 self.message.body.has(tag::MATURITY_DAY)
329 }
330
331
332
333
334 pub fn set_maturity_month_year(&mut self, v: String) {
336 self.message.body.set_field(tag::MATURITY_MONTH_YEAR, FIXString::from(v));
337 }
338
339 pub fn get_maturity_month_year(&self) -> Result<String, MessageRejectErrorEnum> {
341 let mut fld = field::MaturityMonthYearField::new(String::new());
342 self.message.body.get_field(tag::MATURITY_MONTH_YEAR, &mut fld.0)?;
343 Ok(fld.value().to_string())
344 }
345
346
347 pub fn has_maturity_month_year(&self) -> bool {
349 self.message.body.has(tag::MATURITY_MONTH_YEAR)
350 }
351
352
353
354
355 pub fn set_net_money(&mut self, val: Decimal, scale: i32) {
357 self.message.body.set_field(tag::NET_MONEY, fixer::fix_decimal::FIXDecimal { decimal: val, scale });
358 }
359
360 pub fn get_net_money(&self) -> Result<Decimal, MessageRejectErrorEnum> {
362 let mut fld = field::NetMoneyField::new(Decimal::ZERO, 0);
363 self.message.body.get_field(tag::NET_MONEY, &mut fld.0)?;
364 Ok(fld.value())
365 }
366
367
368 pub fn has_net_money(&self) -> bool {
370 self.message.body.has(tag::NET_MONEY)
371 }
372
373
374
375
376 pub fn set_no_allocs(&mut self, v: isize) {
378 self.message.body.set_field(tag::NO_ALLOCS, fixer::fix_int::FIXInt::from(v));
379 }
380
381 pub fn get_no_allocs(&self) -> Result<isize, MessageRejectErrorEnum> {
383 let mut fld = field::NoAllocsField::new(0);
384 self.message.body.get_field(tag::NO_ALLOCS, &mut fld.0)?;
385 Ok(fld.value())
386 }
387
388
389 pub fn has_no_allocs(&self) -> bool {
391 self.message.body.has(tag::NO_ALLOCS)
392 }
393
394
395
396
397 pub fn set_no_execs(&mut self, v: isize) {
399 self.message.body.set_field(tag::NO_EXECS, fixer::fix_int::FIXInt::from(v));
400 }
401
402 pub fn get_no_execs(&self) -> Result<isize, MessageRejectErrorEnum> {
404 let mut fld = field::NoExecsField::new(0);
405 self.message.body.get_field(tag::NO_EXECS, &mut fld.0)?;
406 Ok(fld.value())
407 }
408
409
410 pub fn has_no_execs(&self) -> bool {
412 self.message.body.has(tag::NO_EXECS)
413 }
414
415
416
417
418 pub fn set_no_orders(&mut self, v: isize) {
420 self.message.body.set_field(tag::NO_ORDERS, fixer::fix_int::FIXInt::from(v));
421 }
422
423 pub fn get_no_orders(&self) -> Result<isize, MessageRejectErrorEnum> {
425 let mut fld = field::NoOrdersField::new(0);
426 self.message.body.get_field(tag::NO_ORDERS, &mut fld.0)?;
427 Ok(fld.value())
428 }
429
430
431 pub fn has_no_orders(&self) -> bool {
433 self.message.body.has(tag::NO_ORDERS)
434 }
435
436
437
438
439 pub fn set_num_days_interest(&mut self, v: isize) {
441 self.message.body.set_field(tag::NUM_DAYS_INTEREST, fixer::fix_int::FIXInt::from(v));
442 }
443
444 pub fn get_num_days_interest(&self) -> Result<isize, MessageRejectErrorEnum> {
446 let mut fld = field::NumDaysInterestField::new(0);
447 self.message.body.get_field(tag::NUM_DAYS_INTEREST, &mut fld.0)?;
448 Ok(fld.value())
449 }
450
451
452 pub fn has_num_days_interest(&self) -> bool {
454 self.message.body.has(tag::NUM_DAYS_INTEREST)
455 }
456
457
458
459
460 pub fn set_open_close(&mut self, v: String) {
462 self.message.body.set_field(tag::OPEN_CLOSE, FIXString::from(v));
463 }
464
465 pub fn get_open_close(&self) -> Result<String, MessageRejectErrorEnum> {
467 let mut fld = field::OpenCloseField::new(String::new());
468 self.message.body.get_field(tag::OPEN_CLOSE, &mut fld.0)?;
469 Ok(fld.value().to_string())
470 }
471
472
473 pub fn has_open_close(&self) -> bool {
475 self.message.body.has(tag::OPEN_CLOSE)
476 }
477
478
479
480
481 pub fn set_opt_attribute(&mut self, v: String) {
483 self.message.body.set_field(tag::OPT_ATTRIBUTE, FIXString::from(v));
484 }
485
486 pub fn get_opt_attribute(&self) -> Result<String, MessageRejectErrorEnum> {
488 let mut fld = field::OptAttributeField::new(String::new());
489 self.message.body.get_field(tag::OPT_ATTRIBUTE, &mut fld.0)?;
490 Ok(fld.value().to_string())
491 }
492
493
494 pub fn has_opt_attribute(&self) -> bool {
496 self.message.body.has(tag::OPT_ATTRIBUTE)
497 }
498
499
500
501
502 pub fn set_put_or_call(&mut self, v: isize) {
504 self.message.body.set_field(tag::PUT_OR_CALL, fixer::fix_int::FIXInt::from(v));
505 }
506
507 pub fn get_put_or_call(&self) -> Result<isize, MessageRejectErrorEnum> {
509 let mut fld = field::PutOrCallField::new(0);
510 self.message.body.get_field(tag::PUT_OR_CALL, &mut fld.0)?;
511 Ok(fld.value())
512 }
513
514
515 pub fn has_put_or_call(&self) -> bool {
517 self.message.body.has(tag::PUT_OR_CALL)
518 }
519
520
521
522
523 pub fn set_ref_alloc_id(&mut self, v: String) {
525 self.message.body.set_field(tag::REF_ALLOC_ID, FIXString::from(v));
526 }
527
528 pub fn get_ref_alloc_id(&self) -> Result<String, MessageRejectErrorEnum> {
530 let mut fld = field::RefAllocIDField::new(String::new());
531 self.message.body.get_field(tag::REF_ALLOC_ID, &mut fld.0)?;
532 Ok(fld.value().to_string())
533 }
534
535
536 pub fn has_ref_alloc_id(&self) -> bool {
538 self.message.body.has(tag::REF_ALLOC_ID)
539 }
540
541
542
543
544 pub fn set_security_desc(&mut self, v: String) {
546 self.message.body.set_field(tag::SECURITY_DESC, FIXString::from(v));
547 }
548
549 pub fn get_security_desc(&self) -> Result<String, MessageRejectErrorEnum> {
551 let mut fld = field::SecurityDescField::new(String::new());
552 self.message.body.get_field(tag::SECURITY_DESC, &mut fld.0)?;
553 Ok(fld.value().to_string())
554 }
555
556
557 pub fn has_security_desc(&self) -> bool {
559 self.message.body.has(tag::SECURITY_DESC)
560 }
561
562
563
564
565 pub fn set_security_exchange(&mut self, v: String) {
567 self.message.body.set_field(tag::SECURITY_EXCHANGE, FIXString::from(v));
568 }
569
570 pub fn get_security_exchange(&self) -> Result<String, MessageRejectErrorEnum> {
572 let mut fld = field::SecurityExchangeField::new(String::new());
573 self.message.body.get_field(tag::SECURITY_EXCHANGE, &mut fld.0)?;
574 Ok(fld.value().to_string())
575 }
576
577
578 pub fn has_security_exchange(&self) -> bool {
580 self.message.body.has(tag::SECURITY_EXCHANGE)
581 }
582
583
584
585
586 pub fn set_security_id(&mut self, v: String) {
588 self.message.body.set_field(tag::SECURITY_ID, FIXString::from(v));
589 }
590
591 pub fn get_security_id(&self) -> Result<String, MessageRejectErrorEnum> {
593 let mut fld = field::SecurityIDField::new(String::new());
594 self.message.body.get_field(tag::SECURITY_ID, &mut fld.0)?;
595 Ok(fld.value().to_string())
596 }
597
598
599 pub fn has_security_id(&self) -> bool {
601 self.message.body.has(tag::SECURITY_ID)
602 }
603
604
605
606
607 pub fn set_security_type(&mut self, v: String) {
609 self.message.body.set_field(tag::SECURITY_TYPE, FIXString::from(v));
610 }
611
612 pub fn get_security_type(&self) -> Result<String, MessageRejectErrorEnum> {
614 let mut fld = field::SecurityTypeField::new(String::new());
615 self.message.body.get_field(tag::SECURITY_TYPE, &mut fld.0)?;
616 Ok(fld.value().to_string())
617 }
618
619
620 pub fn has_security_type(&self) -> bool {
622 self.message.body.has(tag::SECURITY_TYPE)
623 }
624
625
626
627
628 pub fn set_settlmnt_typ(&mut self, v: String) {
630 self.message.body.set_field(tag::SETTLMNT_TYP, FIXString::from(v));
631 }
632
633 pub fn get_settlmnt_typ(&self) -> Result<String, MessageRejectErrorEnum> {
635 let mut fld = field::SettlmntTypField::new(String::new());
636 self.message.body.get_field(tag::SETTLMNT_TYP, &mut fld.0)?;
637 Ok(fld.value().to_string())
638 }
639
640
641 pub fn has_settlmnt_typ(&self) -> bool {
643 self.message.body.has(tag::SETTLMNT_TYP)
644 }
645
646
647
648
649 pub fn set_shares(&mut self, val: Decimal, scale: i32) {
651 self.message.body.set_field(tag::SHARES, fixer::fix_decimal::FIXDecimal { decimal: val, scale });
652 }
653
654 pub fn get_shares(&self) -> Result<Decimal, MessageRejectErrorEnum> {
656 let mut fld = field::SharesField::new(Decimal::ZERO, 0);
657 self.message.body.get_field(tag::SHARES, &mut fld.0)?;
658 Ok(fld.value())
659 }
660
661
662 pub fn has_shares(&self) -> bool {
664 self.message.body.has(tag::SHARES)
665 }
666
667
668
669
670 pub fn set_side(&mut self, v: String) {
672 self.message.body.set_field(tag::SIDE, FIXString::from(v));
673 }
674
675 pub fn get_side(&self) -> Result<String, MessageRejectErrorEnum> {
677 let mut fld = field::SideField::new(String::new());
678 self.message.body.get_field(tag::SIDE, &mut fld.0)?;
679 Ok(fld.value().to_string())
680 }
681
682
683 pub fn has_side(&self) -> bool {
685 self.message.body.has(tag::SIDE)
686 }
687
688
689
690
691 pub fn set_strike_price(&mut self, val: Decimal, scale: i32) {
693 self.message.body.set_field(tag::STRIKE_PRICE, fixer::fix_decimal::FIXDecimal { decimal: val, scale });
694 }
695
696 pub fn get_strike_price(&self) -> Result<Decimal, MessageRejectErrorEnum> {
698 let mut fld = field::StrikePriceField::new(Decimal::ZERO, 0);
699 self.message.body.get_field(tag::STRIKE_PRICE, &mut fld.0)?;
700 Ok(fld.value())
701 }
702
703
704 pub fn has_strike_price(&self) -> bool {
706 self.message.body.has(tag::STRIKE_PRICE)
707 }
708
709
710
711
712 pub fn set_symbol(&mut self, v: String) {
714 self.message.body.set_field(tag::SYMBOL, FIXString::from(v));
715 }
716
717 pub fn get_symbol(&self) -> Result<String, MessageRejectErrorEnum> {
719 let mut fld = field::SymbolField::new(String::new());
720 self.message.body.get_field(tag::SYMBOL, &mut fld.0)?;
721 Ok(fld.value().to_string())
722 }
723
724
725 pub fn has_symbol(&self) -> bool {
727 self.message.body.has(tag::SYMBOL)
728 }
729
730
731
732
733 pub fn set_symbol_sfx(&mut self, v: String) {
735 self.message.body.set_field(tag::SYMBOL_SFX, FIXString::from(v));
736 }
737
738 pub fn get_symbol_sfx(&self) -> Result<String, MessageRejectErrorEnum> {
740 let mut fld = field::SymbolSfxField::new(String::new());
741 self.message.body.get_field(tag::SYMBOL_SFX, &mut fld.0)?;
742 Ok(fld.value().to_string())
743 }
744
745
746 pub fn has_symbol_sfx(&self) -> bool {
748 self.message.body.has(tag::SYMBOL_SFX)
749 }
750
751
752
753
754 pub fn set_text(&mut self, v: String) {
756 self.message.body.set_field(tag::TEXT, FIXString::from(v));
757 }
758
759 pub fn get_text(&self) -> Result<String, MessageRejectErrorEnum> {
761 let mut fld = field::TextField::new(String::new());
762 self.message.body.get_field(tag::TEXT, &mut fld.0)?;
763 Ok(fld.value().to_string())
764 }
765
766
767 pub fn has_text(&self) -> bool {
769 self.message.body.has(tag::TEXT)
770 }
771
772
773
774
775 pub fn set_trade_date(&mut self, v: String) {
777 self.message.body.set_field(tag::TRADE_DATE, FIXString::from(v));
778 }
779
780 pub fn get_trade_date(&self) -> Result<String, MessageRejectErrorEnum> {
782 let mut fld = field::TradeDateField::new(String::new());
783 self.message.body.get_field(tag::TRADE_DATE, &mut fld.0)?;
784 Ok(fld.value().to_string())
785 }
786
787
788 pub fn has_trade_date(&self) -> bool {
790 self.message.body.has(tag::TRADE_DATE)
791 }
792
793
794
795
796 pub fn set_transact_time(&mut self, v: Timestamp) {
798 self.message.body.set_field(tag::TRANSACT_TIME, fixer::fix_utc_timestamp::FIXUTCTimestamp {
799 time: v,
800 precision: fixer::fix_utc_timestamp::TimestampPrecision::Millis,
801 });
802 }
803
804 pub fn get_transact_time(&self) -> Result<Timestamp, MessageRejectErrorEnum> {
806 let mut fld = field::TransactTimeField::new(Timestamp::UNIX_EPOCH);
807 self.message.body.get_field(tag::TRANSACT_TIME, &mut fld.0)?;
808 Ok(fld.value())
809 }
810
811
812 pub fn has_transact_time(&self) -> bool {
814 self.message.body.has(tag::TRANSACT_TIME)
815 }
816
817
818}
819
820pub type RouteOut = fn(msg: Allocation, session_id: SessionID) -> Result<(), MessageRejectErrorEnum>;
822
823pub type Route = (&'static str, &'static str, Box<dyn Fn(&Message, SessionID) -> Result<(), MessageRejectErrorEnum> + Send>);
825
826pub fn route(router: RouteOut) -> Route {
828 let r = move |msg: &Message, session_id: SessionID| -> Result<(), MessageRejectErrorEnum> {
829 router(Allocation::from_message(msg.clone()), session_id)
830 };
831 ("FIX.4.1", "J", Box::new(r))
832}