1use frame_support::traits::{
23 tokens::{
24 fungibles, fungibles::imbalance, AssetId, DepositConsequence, Fortitude, Precision,
25 Preservation, Provenance, Restriction, WithdrawConsequence,
26 },
27 AccountTouch,
28};
29use sp_runtime::{
30 traits::Convert,
31 DispatchError, DispatchResult, Either,
32 Either::{Left, Right},
33};
34
35pub struct UnionOf<Left, Right, Criterion, AssetKind, AccountId>(
44 core::marker::PhantomData<(Left, Right, Criterion, AssetKind, AccountId)>,
45);
46
47impl<
48 Left: fungibles::Inspect<AccountId>,
49 Right: fungibles::Inspect<AccountId, Balance = Left::Balance>,
50 Criterion: Convert<AssetKind, Either<Left::AssetId, Right::AssetId>>,
51 AssetKind: AssetId,
52 AccountId,
53 > fungibles::Inspect<AccountId> for UnionOf<Left, Right, Criterion, AssetKind, AccountId>
54{
55 type AssetId = AssetKind;
56 type Balance = Left::Balance;
57
58 fn total_issuance(asset: Self::AssetId) -> Self::Balance {
59 match Criterion::convert(asset) {
60 Left(a) => <Left as fungibles::Inspect<AccountId>>::total_issuance(a),
61 Right(a) => <Right as fungibles::Inspect<AccountId>>::total_issuance(a),
62 }
63 }
64 fn active_issuance(asset: Self::AssetId) -> Self::Balance {
65 match Criterion::convert(asset) {
66 Left(a) => <Left as fungibles::Inspect<AccountId>>::active_issuance(a),
67 Right(a) => <Right as fungibles::Inspect<AccountId>>::active_issuance(a),
68 }
69 }
70 fn minimum_balance(asset: Self::AssetId) -> Self::Balance {
71 match Criterion::convert(asset) {
72 Left(a) => <Left as fungibles::Inspect<AccountId>>::minimum_balance(a),
73 Right(a) => <Right as fungibles::Inspect<AccountId>>::minimum_balance(a),
74 }
75 }
76 fn balance(asset: Self::AssetId, who: &AccountId) -> Self::Balance {
77 match Criterion::convert(asset) {
78 Left(a) => <Left as fungibles::Inspect<AccountId>>::balance(a, who),
79 Right(a) => <Right as fungibles::Inspect<AccountId>>::balance(a, who),
80 }
81 }
82 fn total_balance(asset: Self::AssetId, who: &AccountId) -> Self::Balance {
83 match Criterion::convert(asset) {
84 Left(a) => <Left as fungibles::Inspect<AccountId>>::total_balance(a, who),
85 Right(a) => <Right as fungibles::Inspect<AccountId>>::total_balance(a, who),
86 }
87 }
88 fn reducible_balance(
89 asset: Self::AssetId,
90 who: &AccountId,
91 preservation: Preservation,
92 force: Fortitude,
93 ) -> Self::Balance {
94 match Criterion::convert(asset) {
95 Left(a) => <Left as fungibles::Inspect<AccountId>>::reducible_balance(
96 a,
97 who,
98 preservation,
99 force,
100 ),
101 Right(a) => <Right as fungibles::Inspect<AccountId>>::reducible_balance(
102 a,
103 who,
104 preservation,
105 force,
106 ),
107 }
108 }
109 fn can_deposit(
110 asset: Self::AssetId,
111 who: &AccountId,
112 amount: Self::Balance,
113 provenance: Provenance,
114 ) -> DepositConsequence {
115 match Criterion::convert(asset) {
116 Left(a) =>
117 <Left as fungibles::Inspect<AccountId>>::can_deposit(a, who, amount, provenance),
118 Right(a) =>
119 <Right as fungibles::Inspect<AccountId>>::can_deposit(a, who, amount, provenance),
120 }
121 }
122 fn can_withdraw(
123 asset: Self::AssetId,
124 who: &AccountId,
125 amount: Self::Balance,
126 ) -> WithdrawConsequence<Self::Balance> {
127 match Criterion::convert(asset) {
128 Left(a) => <Left as fungibles::Inspect<AccountId>>::can_withdraw(a, who, amount),
129 Right(a) => <Right as fungibles::Inspect<AccountId>>::can_withdraw(a, who, amount),
130 }
131 }
132 fn asset_exists(asset: Self::AssetId) -> bool {
133 match Criterion::convert(asset) {
134 Left(a) => <Left as fungibles::Inspect<AccountId>>::asset_exists(a),
135 Right(a) => <Right as fungibles::Inspect<AccountId>>::asset_exists(a),
136 }
137 }
138}
139
140impl<
141 Left: fungibles::InspectHold<AccountId>,
142 Right: fungibles::InspectHold<AccountId, Balance = Left::Balance, Reason = Left::Reason>,
143 Criterion: Convert<AssetKind, Either<Left::AssetId, Right::AssetId>>,
144 AssetKind: AssetId,
145 AccountId,
146 > fungibles::InspectHold<AccountId> for UnionOf<Left, Right, Criterion, AssetKind, AccountId>
147{
148 type Reason = Left::Reason;
149
150 fn reducible_total_balance_on_hold(
151 asset: Self::AssetId,
152 who: &AccountId,
153 force: Fortitude,
154 ) -> Self::Balance {
155 match Criterion::convert(asset) {
156 Left(a) =>
157 <Left as fungibles::InspectHold<AccountId>>::reducible_total_balance_on_hold(
158 a, who, force,
159 ),
160 Right(a) =>
161 <Right as fungibles::InspectHold<AccountId>>::reducible_total_balance_on_hold(
162 a, who, force,
163 ),
164 }
165 }
166 fn hold_available(asset: Self::AssetId, reason: &Self::Reason, who: &AccountId) -> bool {
167 match Criterion::convert(asset) {
168 Left(a) => <Left as fungibles::InspectHold<AccountId>>::hold_available(a, reason, who),
169 Right(a) =>
170 <Right as fungibles::InspectHold<AccountId>>::hold_available(a, reason, who),
171 }
172 }
173 fn total_balance_on_hold(asset: Self::AssetId, who: &AccountId) -> Self::Balance {
174 match Criterion::convert(asset) {
175 Left(a) => <Left as fungibles::InspectHold<AccountId>>::total_balance_on_hold(a, who),
176 Right(a) => <Right as fungibles::InspectHold<AccountId>>::total_balance_on_hold(a, who),
177 }
178 }
179 fn balance_on_hold(
180 asset: Self::AssetId,
181 reason: &Self::Reason,
182 who: &AccountId,
183 ) -> Self::Balance {
184 match Criterion::convert(asset) {
185 Left(a) => <Left as fungibles::InspectHold<AccountId>>::balance_on_hold(a, reason, who),
186 Right(a) =>
187 <Right as fungibles::InspectHold<AccountId>>::balance_on_hold(a, reason, who),
188 }
189 }
190 fn can_hold(
191 asset: Self::AssetId,
192 reason: &Self::Reason,
193 who: &AccountId,
194 amount: Self::Balance,
195 ) -> bool {
196 match Criterion::convert(asset) {
197 Left(a) =>
198 <Left as fungibles::InspectHold<AccountId>>::can_hold(a, reason, who, amount),
199 Right(a) =>
200 <Right as fungibles::InspectHold<AccountId>>::can_hold(a, reason, who, amount),
201 }
202 }
203}
204
205impl<
206 Left: fungibles::InspectFreeze<AccountId>,
207 Right: fungibles::InspectFreeze<AccountId, Balance = Left::Balance, Id = Left::Id>,
208 Criterion: Convert<AssetKind, Either<Left::AssetId, Right::AssetId>>,
209 AssetKind: AssetId,
210 AccountId,
211 > fungibles::InspectFreeze<AccountId> for UnionOf<Left, Right, Criterion, AssetKind, AccountId>
212{
213 type Id = Left::Id;
214 fn balance_frozen(asset: Self::AssetId, id: &Self::Id, who: &AccountId) -> Self::Balance {
215 match Criterion::convert(asset) {
216 Left(a) => <Left as fungibles::InspectFreeze<AccountId>>::balance_frozen(a, id, who),
217 Right(a) => <Right as fungibles::InspectFreeze<AccountId>>::balance_frozen(a, id, who),
218 }
219 }
220 fn balance_freezable(asset: Self::AssetId, who: &AccountId) -> Self::Balance {
221 match Criterion::convert(asset) {
222 Left(a) => <Left as fungibles::InspectFreeze<AccountId>>::balance_freezable(a, who),
223 Right(a) => <Right as fungibles::InspectFreeze<AccountId>>::balance_freezable(a, who),
224 }
225 }
226 fn can_freeze(asset: Self::AssetId, id: &Self::Id, who: &AccountId) -> bool {
227 match Criterion::convert(asset) {
228 Left(a) => <Left as fungibles::InspectFreeze<AccountId>>::can_freeze(a, id, who),
229 Right(a) => <Right as fungibles::InspectFreeze<AccountId>>::can_freeze(a, id, who),
230 }
231 }
232}
233
234impl<
235 Left: fungibles::Unbalanced<AccountId>,
236 Right: fungibles::Unbalanced<AccountId, Balance = Left::Balance>,
237 Criterion: Convert<AssetKind, Either<Left::AssetId, Right::AssetId>>,
238 AssetKind: AssetId,
239 AccountId,
240 > fungibles::Unbalanced<AccountId> for UnionOf<Left, Right, Criterion, AssetKind, AccountId>
241{
242 fn handle_dust(dust: fungibles::Dust<AccountId, Self>)
243 where
244 Self: Sized,
245 {
246 match Criterion::convert(dust.0) {
247 Left(a) =>
248 <Left as fungibles::Unbalanced<AccountId>>::handle_dust(fungibles::Dust(a, dust.1)),
249 Right(a) =>
250 <Right as fungibles::Unbalanced<AccountId>>::handle_dust(fungibles::Dust(a, dust.1)),
251 }
252 }
253 fn write_balance(
254 asset: Self::AssetId,
255 who: &AccountId,
256 amount: Self::Balance,
257 ) -> Result<Option<Self::Balance>, DispatchError> {
258 match Criterion::convert(asset) {
259 Left(a) => <Left as fungibles::Unbalanced<AccountId>>::write_balance(a, who, amount),
260 Right(a) => <Right as fungibles::Unbalanced<AccountId>>::write_balance(a, who, amount),
261 }
262 }
263 fn set_total_issuance(asset: Self::AssetId, amount: Self::Balance) -> () {
264 match Criterion::convert(asset) {
265 Left(a) => <Left as fungibles::Unbalanced<AccountId>>::set_total_issuance(a, amount),
266 Right(a) => <Right as fungibles::Unbalanced<AccountId>>::set_total_issuance(a, amount),
267 }
268 }
269 fn decrease_balance(
270 asset: Self::AssetId,
271 who: &AccountId,
272 amount: Self::Balance,
273 precision: Precision,
274 preservation: Preservation,
275 force: Fortitude,
276 ) -> Result<Self::Balance, DispatchError> {
277 match Criterion::convert(asset) {
278 Left(a) => <Left as fungibles::Unbalanced<AccountId>>::decrease_balance(
279 a,
280 who,
281 amount,
282 precision,
283 preservation,
284 force,
285 ),
286 Right(a) => <Right as fungibles::Unbalanced<AccountId>>::decrease_balance(
287 a,
288 who,
289 amount,
290 precision,
291 preservation,
292 force,
293 ),
294 }
295 }
296 fn increase_balance(
297 asset: Self::AssetId,
298 who: &AccountId,
299 amount: Self::Balance,
300 precision: Precision,
301 ) -> Result<Self::Balance, DispatchError> {
302 match Criterion::convert(asset) {
303 Left(a) => <Left as fungibles::Unbalanced<AccountId>>::increase_balance(
304 a, who, amount, precision,
305 ),
306 Right(a) => <Right as fungibles::Unbalanced<AccountId>>::increase_balance(
307 a, who, amount, precision,
308 ),
309 }
310 }
311}
312
313impl<
314 Left: fungibles::UnbalancedHold<AccountId>,
315 Right: fungibles::UnbalancedHold<AccountId, Balance = Left::Balance, Reason = Left::Reason>,
316 Criterion: Convert<AssetKind, Either<Left::AssetId, Right::AssetId>>,
317 AssetKind: AssetId,
318 AccountId,
319 > fungibles::UnbalancedHold<AccountId> for UnionOf<Left, Right, Criterion, AssetKind, AccountId>
320{
321 fn set_balance_on_hold(
322 asset: Self::AssetId,
323 reason: &Self::Reason,
324 who: &AccountId,
325 amount: Self::Balance,
326 ) -> DispatchResult {
327 match Criterion::convert(asset) {
328 Left(a) => <Left as fungibles::UnbalancedHold<AccountId>>::set_balance_on_hold(
329 a, reason, who, amount,
330 ),
331 Right(a) => <Right as fungibles::UnbalancedHold<AccountId>>::set_balance_on_hold(
332 a, reason, who, amount,
333 ),
334 }
335 }
336 fn decrease_balance_on_hold(
337 asset: Self::AssetId,
338 reason: &Self::Reason,
339 who: &AccountId,
340 amount: Self::Balance,
341 precision: Precision,
342 ) -> Result<Self::Balance, DispatchError> {
343 match Criterion::convert(asset) {
344 Left(a) => <Left as fungibles::UnbalancedHold<AccountId>>::decrease_balance_on_hold(
345 a, reason, who, amount, precision,
346 ),
347 Right(a) => <Right as fungibles::UnbalancedHold<AccountId>>::decrease_balance_on_hold(
348 a, reason, who, amount, precision,
349 ),
350 }
351 }
352 fn increase_balance_on_hold(
353 asset: Self::AssetId,
354 reason: &Self::Reason,
355 who: &AccountId,
356 amount: Self::Balance,
357 precision: Precision,
358 ) -> Result<Self::Balance, DispatchError> {
359 match Criterion::convert(asset) {
360 Left(a) => <Left as fungibles::UnbalancedHold<AccountId>>::increase_balance_on_hold(
361 a, reason, who, amount, precision,
362 ),
363 Right(a) => <Right as fungibles::UnbalancedHold<AccountId>>::increase_balance_on_hold(
364 a, reason, who, amount, precision,
365 ),
366 }
367 }
368}
369
370impl<
371 Left: fungibles::Mutate<AccountId>,
372 Right: fungibles::Mutate<AccountId, Balance = Left::Balance>,
373 Criterion: Convert<AssetKind, Either<Left::AssetId, Right::AssetId>>,
374 AssetKind: AssetId,
375 AccountId: Eq,
376 > fungibles::Mutate<AccountId> for UnionOf<Left, Right, Criterion, AssetKind, AccountId>
377{
378 fn mint_into(
379 asset: Self::AssetId,
380 who: &AccountId,
381 amount: Self::Balance,
382 ) -> Result<Self::Balance, DispatchError> {
383 match Criterion::convert(asset) {
384 Left(a) => <Left as fungibles::Mutate<AccountId>>::mint_into(a, who, amount),
385 Right(a) => <Right as fungibles::Mutate<AccountId>>::mint_into(a, who, amount),
386 }
387 }
388 fn burn_from(
389 asset: Self::AssetId,
390 who: &AccountId,
391 amount: Self::Balance,
392 preservation: Preservation,
393 precision: Precision,
394 force: Fortitude,
395 ) -> Result<Self::Balance, DispatchError> {
396 match Criterion::convert(asset) {
397 Left(a) => <Left as fungibles::Mutate<AccountId>>::burn_from(
398 a,
399 who,
400 amount,
401 preservation,
402 precision,
403 force,
404 ),
405 Right(a) => <Right as fungibles::Mutate<AccountId>>::burn_from(
406 a,
407 who,
408 amount,
409 preservation,
410 precision,
411 force,
412 ),
413 }
414 }
415 fn shelve(
416 asset: Self::AssetId,
417 who: &AccountId,
418 amount: Self::Balance,
419 ) -> Result<Self::Balance, DispatchError> {
420 match Criterion::convert(asset) {
421 Left(a) => <Left as fungibles::Mutate<AccountId>>::shelve(a, who, amount),
422 Right(a) => <Right as fungibles::Mutate<AccountId>>::shelve(a, who, amount),
423 }
424 }
425 fn restore(
426 asset: Self::AssetId,
427 who: &AccountId,
428 amount: Self::Balance,
429 ) -> Result<Self::Balance, DispatchError> {
430 match Criterion::convert(asset) {
431 Left(a) => <Left as fungibles::Mutate<AccountId>>::restore(a, who, amount),
432 Right(a) => <Right as fungibles::Mutate<AccountId>>::restore(a, who, amount),
433 }
434 }
435 fn transfer(
436 asset: Self::AssetId,
437 source: &AccountId,
438 dest: &AccountId,
439 amount: Self::Balance,
440 preservation: Preservation,
441 ) -> Result<Self::Balance, DispatchError> {
442 match Criterion::convert(asset) {
443 Left(a) => <Left as fungibles::Mutate<AccountId>>::transfer(
444 a,
445 source,
446 dest,
447 amount,
448 preservation,
449 ),
450 Right(a) => <Right as fungibles::Mutate<AccountId>>::transfer(
451 a,
452 source,
453 dest,
454 amount,
455 preservation,
456 ),
457 }
458 }
459
460 fn set_balance(asset: Self::AssetId, who: &AccountId, amount: Self::Balance) -> Self::Balance {
461 match Criterion::convert(asset) {
462 Left(a) => <Left as fungibles::Mutate<AccountId>>::set_balance(a, who, amount),
463 Right(a) => <Right as fungibles::Mutate<AccountId>>::set_balance(a, who, amount),
464 }
465 }
466}
467
468impl<
469 Left: fungibles::MutateHold<AccountId>,
470 Right: fungibles::MutateHold<AccountId, Balance = Left::Balance, Reason = Left::Reason>,
471 Criterion: Convert<AssetKind, Either<Left::AssetId, Right::AssetId>>,
472 AssetKind: AssetId,
473 AccountId,
474 > fungibles::MutateHold<AccountId> for UnionOf<Left, Right, Criterion, AssetKind, AccountId>
475{
476 fn hold(
477 asset: Self::AssetId,
478 reason: &Self::Reason,
479 who: &AccountId,
480 amount: Self::Balance,
481 ) -> DispatchResult {
482 match Criterion::convert(asset) {
483 Left(a) => <Left as fungibles::MutateHold<AccountId>>::hold(a, reason, who, amount),
484 Right(a) => <Right as fungibles::MutateHold<AccountId>>::hold(a, reason, who, amount),
485 }
486 }
487 fn release(
488 asset: Self::AssetId,
489 reason: &Self::Reason,
490 who: &AccountId,
491 amount: Self::Balance,
492 precision: Precision,
493 ) -> Result<Self::Balance, DispatchError> {
494 match Criterion::convert(asset) {
495 Left(a) => <Left as fungibles::MutateHold<AccountId>>::release(
496 a, reason, who, amount, precision,
497 ),
498 Right(a) => <Right as fungibles::MutateHold<AccountId>>::release(
499 a, reason, who, amount, precision,
500 ),
501 }
502 }
503 fn burn_held(
504 asset: Self::AssetId,
505 reason: &Self::Reason,
506 who: &AccountId,
507 amount: Self::Balance,
508 precision: Precision,
509 force: Fortitude,
510 ) -> Result<Self::Balance, DispatchError> {
511 match Criterion::convert(asset) {
512 Left(a) => <Left as fungibles::MutateHold<AccountId>>::burn_held(
513 a, reason, who, amount, precision, force,
514 ),
515 Right(a) => <Right as fungibles::MutateHold<AccountId>>::burn_held(
516 a, reason, who, amount, precision, force,
517 ),
518 }
519 }
520 fn transfer_on_hold(
521 asset: Self::AssetId,
522 reason: &Self::Reason,
523 source: &AccountId,
524 dest: &AccountId,
525 amount: Self::Balance,
526 precision: Precision,
527 mode: Restriction,
528 force: Fortitude,
529 ) -> Result<Self::Balance, DispatchError> {
530 match Criterion::convert(asset) {
531 Left(a) => <Left as fungibles::MutateHold<AccountId>>::transfer_on_hold(
532 a, reason, source, dest, amount, precision, mode, force,
533 ),
534 Right(a) => <Right as fungibles::MutateHold<AccountId>>::transfer_on_hold(
535 a, reason, source, dest, amount, precision, mode, force,
536 ),
537 }
538 }
539 fn transfer_and_hold(
540 asset: Self::AssetId,
541 reason: &Self::Reason,
542 source: &AccountId,
543 dest: &AccountId,
544 amount: Self::Balance,
545 precision: Precision,
546 preservation: Preservation,
547 force: Fortitude,
548 ) -> Result<Self::Balance, DispatchError> {
549 match Criterion::convert(asset) {
550 Left(a) => <Left as fungibles::MutateHold<AccountId>>::transfer_and_hold(
551 a,
552 reason,
553 source,
554 dest,
555 amount,
556 precision,
557 preservation,
558 force,
559 ),
560 Right(a) => <Right as fungibles::MutateHold<AccountId>>::transfer_and_hold(
561 a,
562 reason,
563 source,
564 dest,
565 amount,
566 precision,
567 preservation,
568 force,
569 ),
570 }
571 }
572}
573
574impl<
575 Left: fungibles::MutateFreeze<AccountId>,
576 Right: fungibles::MutateFreeze<AccountId, Balance = Left::Balance, Id = Left::Id>,
577 Criterion: Convert<AssetKind, Either<Left::AssetId, Right::AssetId>>,
578 AssetKind: AssetId,
579 AccountId,
580 > fungibles::MutateFreeze<AccountId> for UnionOf<Left, Right, Criterion, AssetKind, AccountId>
581{
582 fn set_freeze(
583 asset: Self::AssetId,
584 id: &Self::Id,
585 who: &AccountId,
586 amount: Self::Balance,
587 ) -> DispatchResult {
588 match Criterion::convert(asset) {
589 Left(a) => <Left as fungibles::MutateFreeze<AccountId>>::set_freeze(a, id, who, amount),
590 Right(a) =>
591 <Right as fungibles::MutateFreeze<AccountId>>::set_freeze(a, id, who, amount),
592 }
593 }
594 fn extend_freeze(
595 asset: Self::AssetId,
596 id: &Self::Id,
597 who: &AccountId,
598 amount: Self::Balance,
599 ) -> DispatchResult {
600 match Criterion::convert(asset) {
601 Left(a) =>
602 <Left as fungibles::MutateFreeze<AccountId>>::extend_freeze(a, id, who, amount),
603 Right(a) =>
604 <Right as fungibles::MutateFreeze<AccountId>>::extend_freeze(a, id, who, amount),
605 }
606 }
607 fn thaw(asset: Self::AssetId, id: &Self::Id, who: &AccountId) -> DispatchResult {
608 match Criterion::convert(asset) {
609 Left(a) => <Left as fungibles::MutateFreeze<AccountId>>::thaw(a, id, who),
610 Right(a) => <Right as fungibles::MutateFreeze<AccountId>>::thaw(a, id, who),
611 }
612 }
613}
614
615pub struct ConvertImbalanceDropHandler<
616 Left,
617 Right,
618 LeftAssetId,
619 RightAssetId,
620 Criterion,
621 AssetKind,
622 Balance,
623 AccountId,
624>(
625 core::marker::PhantomData<(
626 Left,
627 Right,
628 LeftAssetId,
629 RightAssetId,
630 Criterion,
631 AssetKind,
632 Balance,
633 AccountId,
634 )>,
635);
636
637impl<
638 Left: fungibles::HandleImbalanceDrop<LeftAssetId, Balance>,
639 Right: fungibles::HandleImbalanceDrop<RightAssetId, Balance>,
640 LeftAssetId,
641 RightAssetId,
642 Criterion: Convert<AssetKind, Either<LeftAssetId, RightAssetId>>,
643 AssetKind,
644 Balance,
645 AccountId,
646 > fungibles::HandleImbalanceDrop<AssetKind, Balance>
647 for ConvertImbalanceDropHandler<
648 Left,
649 Right,
650 LeftAssetId,
651 RightAssetId,
652 Criterion,
653 AssetKind,
654 Balance,
655 AccountId,
656 >
657{
658 fn handle(asset: AssetKind, amount: Balance) {
659 match Criterion::convert(asset) {
660 Left(a) => Left::handle(a, amount),
661 Right(a) => Right::handle(a, amount),
662 }
663 }
664}
665
666impl<
667 Left: fungibles::Balanced<AccountId>,
668 Right: fungibles::Balanced<AccountId, Balance = Left::Balance>,
669 Criterion: Convert<AssetKind, Either<Left::AssetId, Right::AssetId>>,
670 AssetKind: AssetId,
671 AccountId,
672 > fungibles::Balanced<AccountId> for UnionOf<Left, Right, Criterion, AssetKind, AccountId>
673{
674 type OnDropDebt = ConvertImbalanceDropHandler<
675 Left::OnDropDebt,
676 Right::OnDropDebt,
677 Left::AssetId,
678 Right::AssetId,
679 Criterion,
680 AssetKind,
681 Left::Balance,
682 AccountId,
683 >;
684 type OnDropCredit = ConvertImbalanceDropHandler<
685 Left::OnDropCredit,
686 Right::OnDropCredit,
687 Left::AssetId,
688 Right::AssetId,
689 Criterion,
690 AssetKind,
691 Left::Balance,
692 AccountId,
693 >;
694
695 fn deposit(
696 asset: Self::AssetId,
697 who: &AccountId,
698 value: Self::Balance,
699 precision: Precision,
700 ) -> Result<fungibles::Debt<AccountId, Self>, DispatchError> {
701 match Criterion::convert(asset.clone()) {
702 Left(a) => <Left as fungibles::Balanced<AccountId>>::deposit(a, who, value, precision)
703 .map(|debt| imbalance::from_fungibles(debt, asset)),
704 Right(a) =>
705 <Right as fungibles::Balanced<AccountId>>::deposit(a, who, value, precision)
706 .map(|debt| imbalance::from_fungibles(debt, asset)),
707 }
708 }
709 fn issue(asset: Self::AssetId, amount: Self::Balance) -> fungibles::Credit<AccountId, Self> {
710 match Criterion::convert(asset.clone()) {
711 Left(a) => {
712 let credit = <Left as fungibles::Balanced<AccountId>>::issue(a, amount);
713 imbalance::from_fungibles(credit, asset)
714 },
715 Right(a) => {
716 let credit = <Right as fungibles::Balanced<AccountId>>::issue(a, amount);
717 imbalance::from_fungibles(credit, asset)
718 },
719 }
720 }
721 fn pair(
722 asset: Self::AssetId,
723 amount: Self::Balance,
724 ) -> Result<(fungibles::Debt<AccountId, Self>, fungibles::Credit<AccountId, Self>), DispatchError>
725 {
726 match Criterion::convert(asset.clone()) {
727 Left(a) => {
728 let (a, b) = <Left as fungibles::Balanced<AccountId>>::pair(a, amount)?;
729 Ok((
730 imbalance::from_fungibles(a, asset.clone()),
731 imbalance::from_fungibles(b, asset),
732 ))
733 },
734 Right(a) => {
735 let (a, b) = <Right as fungibles::Balanced<AccountId>>::pair(a, amount)?;
736 Ok((
737 imbalance::from_fungibles(a, asset.clone()),
738 imbalance::from_fungibles(b, asset),
739 ))
740 },
741 }
742 }
743 fn rescind(asset: Self::AssetId, amount: Self::Balance) -> fungibles::Debt<AccountId, Self> {
744 match Criterion::convert(asset.clone()) {
745 Left(a) => {
746 let debt = <Left as fungibles::Balanced<AccountId>>::rescind(a, amount);
747 imbalance::from_fungibles(debt, asset)
748 },
749 Right(a) => {
750 let debt = <Right as fungibles::Balanced<AccountId>>::rescind(a, amount);
751 imbalance::from_fungibles(debt, asset)
752 },
753 }
754 }
755 fn resolve(
756 who: &AccountId,
757 credit: fungibles::Credit<AccountId, Self>,
758 ) -> Result<(), fungibles::Credit<AccountId, Self>> {
759 let asset = credit.asset();
760 match Criterion::convert(asset.clone()) {
761 Left(a) => {
762 let credit = imbalance::from_fungibles(credit, a);
763 <Left as fungibles::Balanced<AccountId>>::resolve(who, credit)
764 .map_err(|credit| imbalance::from_fungibles(credit, asset))
765 },
766 Right(a) => {
767 let credit = imbalance::from_fungibles(credit, a);
768 <Right as fungibles::Balanced<AccountId>>::resolve(who, credit)
769 .map_err(|credit| imbalance::from_fungibles(credit, asset))
770 },
771 }
772 }
773 fn settle(
774 who: &AccountId,
775 debt: fungibles::Debt<AccountId, Self>,
776 preservation: Preservation,
777 ) -> Result<fungibles::Credit<AccountId, Self>, fungibles::Debt<AccountId, Self>> {
778 let asset = debt.asset();
779 match Criterion::convert(asset.clone()) {
780 Left(a) => {
781 let debt = imbalance::from_fungibles(debt, a);
782 match <Left as fungibles::Balanced<AccountId>>::settle(who, debt, preservation) {
783 Ok(credit) => Ok(imbalance::from_fungibles(credit, asset)),
784 Err(debt) => Err(imbalance::from_fungibles(debt, asset)),
785 }
786 },
787 Right(a) => {
788 let debt = imbalance::from_fungibles(debt, a);
789 match <Right as fungibles::Balanced<AccountId>>::settle(who, debt, preservation) {
790 Ok(credit) => Ok(imbalance::from_fungibles(credit, asset)),
791 Err(debt) => Err(imbalance::from_fungibles(debt, asset)),
792 }
793 },
794 }
795 }
796 fn withdraw(
797 asset: Self::AssetId,
798 who: &AccountId,
799 value: Self::Balance,
800 precision: Precision,
801 preservation: Preservation,
802 force: Fortitude,
803 ) -> Result<fungibles::Credit<AccountId, Self>, DispatchError> {
804 match Criterion::convert(asset.clone()) {
805 Left(a) => <Left as fungibles::Balanced<AccountId>>::withdraw(
806 a,
807 who,
808 value,
809 precision,
810 preservation,
811 force,
812 )
813 .map(|credit| imbalance::from_fungibles(credit, asset)),
814 Right(a) => <Right as fungibles::Balanced<AccountId>>::withdraw(
815 a,
816 who,
817 value,
818 precision,
819 preservation,
820 force,
821 )
822 .map(|credit| imbalance::from_fungibles(credit, asset)),
823 }
824 }
825}
826
827impl<
828 Left: fungibles::BalancedHold<AccountId>
829 + fungibles::hold::DoneSlash<Self::AssetId, Self::Reason, AccountId, Self::Balance>,
830 Right: fungibles::BalancedHold<AccountId, Balance = Left::Balance, Reason = Left::Reason>
831 + fungibles::hold::DoneSlash<Self::AssetId, Self::Reason, AccountId, Self::Balance>,
832 Criterion: Convert<AssetKind, Either<Left::AssetId, Right::AssetId>>,
833 AssetKind: AssetId,
834 AccountId,
835 > fungibles::BalancedHold<AccountId> for UnionOf<Left, Right, Criterion, AssetKind, AccountId>
836{
837 fn slash(
838 asset: Self::AssetId,
839 reason: &Self::Reason,
840 who: &AccountId,
841 amount: Self::Balance,
842 ) -> (fungibles::Credit<AccountId, Self>, Self::Balance) {
843 match Criterion::convert(asset.clone()) {
844 Left(a) => {
845 let (credit, amount) =
846 <Left as fungibles::BalancedHold<AccountId>>::slash(a, reason, who, amount);
847 (imbalance::from_fungibles(credit, asset), amount)
848 },
849 Right(a) => {
850 let (credit, amount) =
851 <Right as fungibles::BalancedHold<AccountId>>::slash(a, reason, who, amount);
852 (imbalance::from_fungibles(credit, asset), amount)
853 },
854 }
855 }
856}
857
858impl<
859 Reason,
860 Balance,
861 Left: fungibles::Inspect<AccountId>
862 + fungibles::hold::DoneSlash<Left::AssetId, Reason, AccountId, Balance>,
863 Right: fungibles::Inspect<AccountId>
864 + fungibles::hold::DoneSlash<Right::AssetId, Reason, AccountId, Balance>,
865 Criterion: Convert<AssetKind, Either<Left::AssetId, Right::AssetId>>,
866 AssetKind: AssetId,
867 AccountId,
868 > fungibles::hold::DoneSlash<AssetKind, Reason, AccountId, Balance>
869 for UnionOf<Left, Right, Criterion, AssetKind, AccountId>
870{
871 fn done_slash(asset: AssetKind, reason: &Reason, who: &AccountId, amount: Balance) {
872 match Criterion::convert(asset.clone()) {
873 Left(a) => {
874 Left::done_slash(a, reason, who, amount);
875 },
876 Right(a) => {
877 Right::done_slash(a, reason, who, amount);
878 },
879 }
880 }
881}
882
883impl<
884 Left: fungibles::Inspect<AccountId> + fungibles::Create<AccountId>,
885 Right: fungibles::Inspect<AccountId, Balance = Left::Balance> + fungibles::Create<AccountId>,
886 Criterion: Convert<AssetKind, Either<Left::AssetId, Right::AssetId>>,
887 AssetKind: AssetId,
888 AccountId,
889 > fungibles::Create<AccountId> for UnionOf<Left, Right, Criterion, AssetKind, AccountId>
890{
891 fn create(
892 asset: AssetKind,
893 admin: AccountId,
894 is_sufficient: bool,
895 min_balance: Self::Balance,
896 ) -> DispatchResult {
897 match Criterion::convert(asset) {
898 Left(a) =>
899 <Left as fungibles::Create<AccountId>>::create(a, admin, is_sufficient, min_balance),
900 Right(a) => <Right as fungibles::Create<AccountId>>::create(
901 a,
902 admin,
903 is_sufficient,
904 min_balance,
905 ),
906 }
907 }
908}
909
910impl<
911 Left: fungibles::Inspect<AccountId> + AccountTouch<Left::AssetId, AccountId>,
912 Right: fungibles::Inspect<AccountId>
913 + AccountTouch<
914 Right::AssetId,
915 AccountId,
916 Balance = <Left as AccountTouch<Left::AssetId, AccountId>>::Balance,
917 >,
918 Criterion: Convert<AssetKind, Either<Left::AssetId, Right::AssetId>>,
919 AssetKind: AssetId,
920 AccountId,
921 > AccountTouch<AssetKind, AccountId> for UnionOf<Left, Right, Criterion, AssetKind, AccountId>
922{
923 type Balance = <Left as AccountTouch<Left::AssetId, AccountId>>::Balance;
924
925 fn deposit_required(asset: AssetKind) -> Self::Balance {
926 match Criterion::convert(asset) {
927 Left(a) => <Left as AccountTouch<Left::AssetId, AccountId>>::deposit_required(a),
928 Right(a) => <Right as AccountTouch<Right::AssetId, AccountId>>::deposit_required(a),
929 }
930 }
931
932 fn should_touch(asset: AssetKind, who: &AccountId) -> bool {
933 match Criterion::convert(asset) {
934 Left(a) => <Left as AccountTouch<Left::AssetId, AccountId>>::should_touch(a, who),
935 Right(a) => <Right as AccountTouch<Right::AssetId, AccountId>>::should_touch(a, who),
936 }
937 }
938
939 fn touch(asset: AssetKind, who: &AccountId, depositor: &AccountId) -> DispatchResult {
940 match Criterion::convert(asset) {
941 Left(a) => <Left as AccountTouch<Left::AssetId, AccountId>>::touch(a, who, depositor),
942 Right(a) =>
943 <Right as AccountTouch<Right::AssetId, AccountId>>::touch(a, who, depositor),
944 }
945 }
946}
947
948impl<
949 Left: fungibles::Inspect<AccountId> + fungibles::Refund<AccountId>,
950 Right: fungibles::Inspect<AccountId>
951 + fungibles::Refund<AccountId, Balance = <Left as fungibles::Refund<AccountId>>::Balance>,
952 Criterion: Convert<
953 AssetKind,
954 Either<
955 <Left as fungibles::Refund<AccountId>>::AssetId,
956 <Right as fungibles::Refund<AccountId>>::AssetId,
957 >,
958 >,
959 AssetKind: AssetId,
960 AccountId,
961 > fungibles::Refund<AccountId> for UnionOf<Left, Right, Criterion, AssetKind, AccountId>
962{
963 type AssetId = AssetKind;
964 type Balance = <Left as fungibles::Refund<AccountId>>::Balance;
965
966 fn deposit_held(asset: AssetKind, who: AccountId) -> Option<(AccountId, Self::Balance)> {
967 match Criterion::convert(asset) {
968 Left(a) => <Left as fungibles::Refund<AccountId>>::deposit_held(a, who),
969 Right(a) => <Right as fungibles::Refund<AccountId>>::deposit_held(a, who),
970 }
971 }
972 fn refund(asset: AssetKind, who: AccountId) -> DispatchResult {
973 match Criterion::convert(asset) {
974 Left(a) => <Left as fungibles::Refund<AccountId>>::refund(a, who),
975 Right(a) => <Right as fungibles::Refund<AccountId>>::refund(a, who),
976 }
977 }
978}