1use super::{Junction, MultiLocation, NetworkId};
20use codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen};
21use core::{mem, result};
22use scale_info::TypeInfo;
23
24pub(crate) const MAX_JUNCTIONS: usize = 8;
26
27#[derive(
33 Copy,
34 Clone,
35 Eq,
36 PartialEq,
37 Ord,
38 PartialOrd,
39 Encode,
40 Decode,
41 DecodeWithMemTracking,
42 Debug,
43 TypeInfo,
44 MaxEncodedLen,
45 serde::Serialize,
46 serde::Deserialize,
47)]
48#[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))]
49#[scale_info(replace_segment("staging_xcm", "xcm"))]
50pub enum Junctions {
51 Here,
53 X1(Junction),
55 X2(Junction, Junction),
57 X3(Junction, Junction, Junction),
59 X4(Junction, Junction, Junction, Junction),
61 X5(Junction, Junction, Junction, Junction, Junction),
63 X6(Junction, Junction, Junction, Junction, Junction, Junction),
65 X7(Junction, Junction, Junction, Junction, Junction, Junction, Junction),
67 X8(Junction, Junction, Junction, Junction, Junction, Junction, Junction, Junction),
69}
70
71macro_rules! impl_junction {
72 ($count:expr, $variant:ident, ($($index:literal),+)) => {
73 impl From<[Junction; $count]> for Junctions {
76 fn from(junctions: [Junction; $count]) -> Self {
77 Self::$variant($(junctions[$index]),*)
78 }
79 }
80 };
81}
82
83impl_junction!(1, X1, (0));
84impl_junction!(2, X2, (0, 1));
85impl_junction!(3, X3, (0, 1, 2));
86impl_junction!(4, X4, (0, 1, 2, 3));
87impl_junction!(5, X5, (0, 1, 2, 3, 4));
88impl_junction!(6, X6, (0, 1, 2, 3, 4, 5));
89impl_junction!(7, X7, (0, 1, 2, 3, 4, 5, 6));
90impl_junction!(8, X8, (0, 1, 2, 3, 4, 5, 6, 7));
91
92pub struct JunctionsIterator(Junctions);
93impl Iterator for JunctionsIterator {
94 type Item = Junction;
95 fn next(&mut self) -> Option<Junction> {
96 self.0.take_first()
97 }
98}
99
100impl DoubleEndedIterator for JunctionsIterator {
101 fn next_back(&mut self) -> Option<Junction> {
102 self.0.take_last()
103 }
104}
105
106pub struct JunctionsRefIterator<'a> {
107 junctions: &'a Junctions,
108 next: usize,
109 back: usize,
110}
111
112impl<'a> Iterator for JunctionsRefIterator<'a> {
113 type Item = &'a Junction;
114 fn next(&mut self) -> Option<&'a Junction> {
115 if self.next.saturating_add(self.back) >= self.junctions.len() {
116 return None
117 }
118
119 let result = self.junctions.at(self.next);
120 self.next += 1;
121 result
122 }
123}
124
125impl<'a> DoubleEndedIterator for JunctionsRefIterator<'a> {
126 fn next_back(&mut self) -> Option<&'a Junction> {
127 let next_back = self.back.saturating_add(1);
128 let index = self.junctions.len().checked_sub(next_back)?;
130 if self.next > index {
131 return None
132 }
133 self.back = next_back;
134
135 self.junctions.at(index)
136 }
137}
138impl<'a> IntoIterator for &'a Junctions {
139 type Item = &'a Junction;
140 type IntoIter = JunctionsRefIterator<'a>;
141 fn into_iter(self) -> Self::IntoIter {
142 JunctionsRefIterator { junctions: self, next: 0, back: 0 }
143 }
144}
145
146impl IntoIterator for Junctions {
147 type Item = Junction;
148 type IntoIter = JunctionsIterator;
149 fn into_iter(self) -> Self::IntoIter {
150 JunctionsIterator(self)
151 }
152}
153
154impl Junctions {
155 pub const fn into_location(self) -> MultiLocation {
159 MultiLocation { parents: 0, interior: self }
160 }
161
162 pub const fn into_exterior(self, n: u8) -> MultiLocation {
167 MultiLocation { parents: n, interior: self }
168 }
169
170 pub fn remove_network_id(&mut self) {
172 self.for_each_mut(Junction::remove_network_id);
173 }
174
175 pub fn invert_target(mut self, target: &MultiLocation) -> Result<MultiLocation, ()> {
178 let mut junctions = Self::Here;
179 for _ in 0..target.parent_count() {
180 junctions = junctions
181 .pushed_front_with(self.take_last().unwrap_or(Junction::OnlyChild))
182 .map_err(|_| ())?;
183 }
184 let parents = target.interior().len() as u8;
185 Ok(MultiLocation::new(parents, junctions))
186 }
187
188 pub fn for_each_mut(&mut self, mut x: impl FnMut(&mut Junction)) {
191 match self {
192 Junctions::Here => {},
193 Junctions::X1(a) => {
194 x(a);
195 },
196 Junctions::X2(a, b) => {
197 x(a);
198 x(b);
199 },
200 Junctions::X3(a, b, c) => {
201 x(a);
202 x(b);
203 x(c);
204 },
205 Junctions::X4(a, b, c, d) => {
206 x(a);
207 x(b);
208 x(c);
209 x(d);
210 },
211 Junctions::X5(a, b, c, d, e) => {
212 x(a);
213 x(b);
214 x(c);
215 x(d);
216 x(e);
217 },
218 Junctions::X6(a, b, c, d, e, f) => {
219 x(a);
220 x(b);
221 x(c);
222 x(d);
223 x(e);
224 x(f);
225 },
226 Junctions::X7(a, b, c, d, e, f, g) => {
227 x(a);
228 x(b);
229 x(c);
230 x(d);
231 x(e);
232 x(f);
233 x(g);
234 },
235 Junctions::X8(a, b, c, d, e, f, g, h) => {
236 x(a);
237 x(b);
238 x(c);
239 x(d);
240 x(e);
241 x(f);
242 x(g);
243 x(h);
244 },
245 }
246 }
247
248 pub fn global_consensus(&self) -> Result<NetworkId, ()> {
253 if let Some(Junction::GlobalConsensus(network)) = self.first() {
254 Ok(*network)
255 } else {
256 Err(())
257 }
258 }
259
260 pub fn split_global(self) -> Result<(NetworkId, Junctions), ()> {
266 match self.split_first() {
267 (location, Some(Junction::GlobalConsensus(network))) => Ok((network, location)),
268 _ => return Err(()),
269 }
270 }
271
272 pub fn within_global(mut self, relative: MultiLocation) -> Result<Self, ()> {
278 if self.len() <= relative.parents as usize {
279 return Err(())
280 }
281 for _ in 0..relative.parents {
282 self.take_last();
283 }
284 for j in relative.interior {
285 self.push(j).map_err(|_| ())?;
286 }
287 Ok(self)
288 }
289
290 pub fn relative_to(mut self, viewer: &Junctions) -> MultiLocation {
292 let mut i = 0;
293 while match (self.first(), viewer.at(i)) {
294 (Some(x), Some(y)) => x == y,
295 _ => false,
296 } {
297 self = self.split_first().0;
298 i += 1;
300 }
301 MultiLocation { parents: (viewer.len() - i) as u8, interior: self }
305 }
306
307 pub fn first(&self) -> Option<&Junction> {
309 match &self {
310 Junctions::Here => None,
311 Junctions::X1(ref a) => Some(a),
312 Junctions::X2(ref a, ..) => Some(a),
313 Junctions::X3(ref a, ..) => Some(a),
314 Junctions::X4(ref a, ..) => Some(a),
315 Junctions::X5(ref a, ..) => Some(a),
316 Junctions::X6(ref a, ..) => Some(a),
317 Junctions::X7(ref a, ..) => Some(a),
318 Junctions::X8(ref a, ..) => Some(a),
319 }
320 }
321
322 pub fn last(&self) -> Option<&Junction> {
324 match &self {
325 Junctions::Here => None,
326 Junctions::X1(ref a) => Some(a),
327 Junctions::X2(.., ref a) => Some(a),
328 Junctions::X3(.., ref a) => Some(a),
329 Junctions::X4(.., ref a) => Some(a),
330 Junctions::X5(.., ref a) => Some(a),
331 Junctions::X6(.., ref a) => Some(a),
332 Junctions::X7(.., ref a) => Some(a),
333 Junctions::X8(.., ref a) => Some(a),
334 }
335 }
336
337 pub fn split_first(self) -> (Junctions, Option<Junction>) {
340 match self {
341 Junctions::Here => (Junctions::Here, None),
342 Junctions::X1(a) => (Junctions::Here, Some(a)),
343 Junctions::X2(a, b) => (Junctions::X1(b), Some(a)),
344 Junctions::X3(a, b, c) => (Junctions::X2(b, c), Some(a)),
345 Junctions::X4(a, b, c, d) => (Junctions::X3(b, c, d), Some(a)),
346 Junctions::X5(a, b, c, d, e) => (Junctions::X4(b, c, d, e), Some(a)),
347 Junctions::X6(a, b, c, d, e, f) => (Junctions::X5(b, c, d, e, f), Some(a)),
348 Junctions::X7(a, b, c, d, e, f, g) => (Junctions::X6(b, c, d, e, f, g), Some(a)),
349 Junctions::X8(a, b, c, d, e, f, g, h) => (Junctions::X7(b, c, d, e, f, g, h), Some(a)),
350 }
351 }
352
353 pub fn split_last(self) -> (Junctions, Option<Junction>) {
356 match self {
357 Junctions::Here => (Junctions::Here, None),
358 Junctions::X1(a) => (Junctions::Here, Some(a)),
359 Junctions::X2(a, b) => (Junctions::X1(a), Some(b)),
360 Junctions::X3(a, b, c) => (Junctions::X2(a, b), Some(c)),
361 Junctions::X4(a, b, c, d) => (Junctions::X3(a, b, c), Some(d)),
362 Junctions::X5(a, b, c, d, e) => (Junctions::X4(a, b, c, d), Some(e)),
363 Junctions::X6(a, b, c, d, e, f) => (Junctions::X5(a, b, c, d, e), Some(f)),
364 Junctions::X7(a, b, c, d, e, f, g) => (Junctions::X6(a, b, c, d, e, f), Some(g)),
365 Junctions::X8(a, b, c, d, e, f, g, h) => (Junctions::X7(a, b, c, d, e, f, g), Some(h)),
366 }
367 }
368
369 pub fn take_first(&mut self) -> Option<Junction> {
371 let mut d = Junctions::Here;
372 mem::swap(&mut *self, &mut d);
373 let (tail, head) = d.split_first();
374 *self = tail;
375 head
376 }
377
378 pub fn take_last(&mut self) -> Option<Junction> {
380 let mut d = Junctions::Here;
381 mem::swap(&mut *self, &mut d);
382 let (head, tail) = d.split_last();
383 *self = head;
384 tail
385 }
386
387 pub fn push(&mut self, new: impl Into<Junction>) -> result::Result<(), Junction> {
389 let new = new.into();
390 let mut dummy = Junctions::Here;
391 mem::swap(self, &mut dummy);
392 match dummy.pushed_with(new) {
393 Ok(s) => {
394 *self = s;
395 Ok(())
396 },
397 Err((s, j)) => {
398 *self = s;
399 Err(j)
400 },
401 }
402 }
403
404 pub fn push_front(&mut self, new: impl Into<Junction>) -> result::Result<(), Junction> {
406 let new = new.into();
407 let mut dummy = Junctions::Here;
408 mem::swap(self, &mut dummy);
409 match dummy.pushed_front_with(new) {
410 Ok(s) => {
411 *self = s;
412 Ok(())
413 },
414 Err((s, j)) => {
415 *self = s;
416 Err(j)
417 },
418 }
419 }
420
421 pub fn pushed_with(self, new: impl Into<Junction>) -> result::Result<Self, (Self, Junction)> {
424 let new = new.into();
425 Ok(match self {
426 Junctions::Here => Junctions::X1(new),
427 Junctions::X1(a) => Junctions::X2(a, new),
428 Junctions::X2(a, b) => Junctions::X3(a, b, new),
429 Junctions::X3(a, b, c) => Junctions::X4(a, b, c, new),
430 Junctions::X4(a, b, c, d) => Junctions::X5(a, b, c, d, new),
431 Junctions::X5(a, b, c, d, e) => Junctions::X6(a, b, c, d, e, new),
432 Junctions::X6(a, b, c, d, e, f) => Junctions::X7(a, b, c, d, e, f, new),
433 Junctions::X7(a, b, c, d, e, f, g) => Junctions::X8(a, b, c, d, e, f, g, new),
434 s => Err((s, new))?,
435 })
436 }
437
438 pub fn pushed_front_with(
441 self,
442 new: impl Into<Junction>,
443 ) -> result::Result<Self, (Self, Junction)> {
444 let new = new.into();
445 Ok(match self {
446 Junctions::Here => Junctions::X1(new),
447 Junctions::X1(a) => Junctions::X2(new, a),
448 Junctions::X2(a, b) => Junctions::X3(new, a, b),
449 Junctions::X3(a, b, c) => Junctions::X4(new, a, b, c),
450 Junctions::X4(a, b, c, d) => Junctions::X5(new, a, b, c, d),
451 Junctions::X5(a, b, c, d, e) => Junctions::X6(new, a, b, c, d, e),
452 Junctions::X6(a, b, c, d, e, f) => Junctions::X7(new, a, b, c, d, e, f),
453 Junctions::X7(a, b, c, d, e, f, g) => Junctions::X8(new, a, b, c, d, e, f, g),
454 s => Err((s, new))?,
455 })
456 }
457
458 pub fn append_with(&mut self, suffix: impl Into<Junctions>) -> Result<(), Junctions> {
470 let suffix = suffix.into();
471 if self.len().saturating_add(suffix.len()) > MAX_JUNCTIONS {
472 return Err(suffix)
473 }
474 for j in suffix.into_iter() {
475 self.push(j).expect("Already checked the sum of the len()s; qed")
476 }
477 Ok(())
478 }
479
480 pub const fn len(&self) -> usize {
482 match &self {
483 Junctions::Here => 0,
484 Junctions::X1(..) => 1,
485 Junctions::X2(..) => 2,
486 Junctions::X3(..) => 3,
487 Junctions::X4(..) => 4,
488 Junctions::X5(..) => 5,
489 Junctions::X6(..) => 6,
490 Junctions::X7(..) => 7,
491 Junctions::X8(..) => 8,
492 }
493 }
494
495 pub fn at(&self, i: usize) -> Option<&Junction> {
498 Some(match (i, self) {
499 (0, Junctions::X1(ref a)) => a,
500 (0, Junctions::X2(ref a, ..)) => a,
501 (0, Junctions::X3(ref a, ..)) => a,
502 (0, Junctions::X4(ref a, ..)) => a,
503 (0, Junctions::X5(ref a, ..)) => a,
504 (0, Junctions::X6(ref a, ..)) => a,
505 (0, Junctions::X7(ref a, ..)) => a,
506 (0, Junctions::X8(ref a, ..)) => a,
507 (1, Junctions::X2(_, ref a)) => a,
508 (1, Junctions::X3(_, ref a, ..)) => a,
509 (1, Junctions::X4(_, ref a, ..)) => a,
510 (1, Junctions::X5(_, ref a, ..)) => a,
511 (1, Junctions::X6(_, ref a, ..)) => a,
512 (1, Junctions::X7(_, ref a, ..)) => a,
513 (1, Junctions::X8(_, ref a, ..)) => a,
514 (2, Junctions::X3(_, _, ref a)) => a,
515 (2, Junctions::X4(_, _, ref a, ..)) => a,
516 (2, Junctions::X5(_, _, ref a, ..)) => a,
517 (2, Junctions::X6(_, _, ref a, ..)) => a,
518 (2, Junctions::X7(_, _, ref a, ..)) => a,
519 (2, Junctions::X8(_, _, ref a, ..)) => a,
520 (3, Junctions::X4(_, _, _, ref a)) => a,
521 (3, Junctions::X5(_, _, _, ref a, ..)) => a,
522 (3, Junctions::X6(_, _, _, ref a, ..)) => a,
523 (3, Junctions::X7(_, _, _, ref a, ..)) => a,
524 (3, Junctions::X8(_, _, _, ref a, ..)) => a,
525 (4, Junctions::X5(_, _, _, _, ref a)) => a,
526 (4, Junctions::X6(_, _, _, _, ref a, ..)) => a,
527 (4, Junctions::X7(_, _, _, _, ref a, ..)) => a,
528 (4, Junctions::X8(_, _, _, _, ref a, ..)) => a,
529 (5, Junctions::X6(_, _, _, _, _, ref a)) => a,
530 (5, Junctions::X7(_, _, _, _, _, ref a, ..)) => a,
531 (5, Junctions::X8(_, _, _, _, _, ref a, ..)) => a,
532 (6, Junctions::X7(_, _, _, _, _, _, ref a)) => a,
533 (6, Junctions::X8(_, _, _, _, _, _, ref a, ..)) => a,
534 (7, Junctions::X8(_, _, _, _, _, _, _, ref a)) => a,
535 _ => return None,
536 })
537 }
538
539 pub fn at_mut(&mut self, i: usize) -> Option<&mut Junction> {
542 Some(match (i, self) {
543 (0, Junctions::X1(ref mut a)) => a,
544 (0, Junctions::X2(ref mut a, ..)) => a,
545 (0, Junctions::X3(ref mut a, ..)) => a,
546 (0, Junctions::X4(ref mut a, ..)) => a,
547 (0, Junctions::X5(ref mut a, ..)) => a,
548 (0, Junctions::X6(ref mut a, ..)) => a,
549 (0, Junctions::X7(ref mut a, ..)) => a,
550 (0, Junctions::X8(ref mut a, ..)) => a,
551 (1, Junctions::X2(_, ref mut a)) => a,
552 (1, Junctions::X3(_, ref mut a, ..)) => a,
553 (1, Junctions::X4(_, ref mut a, ..)) => a,
554 (1, Junctions::X5(_, ref mut a, ..)) => a,
555 (1, Junctions::X6(_, ref mut a, ..)) => a,
556 (1, Junctions::X7(_, ref mut a, ..)) => a,
557 (1, Junctions::X8(_, ref mut a, ..)) => a,
558 (2, Junctions::X3(_, _, ref mut a)) => a,
559 (2, Junctions::X4(_, _, ref mut a, ..)) => a,
560 (2, Junctions::X5(_, _, ref mut a, ..)) => a,
561 (2, Junctions::X6(_, _, ref mut a, ..)) => a,
562 (2, Junctions::X7(_, _, ref mut a, ..)) => a,
563 (2, Junctions::X8(_, _, ref mut a, ..)) => a,
564 (3, Junctions::X4(_, _, _, ref mut a)) => a,
565 (3, Junctions::X5(_, _, _, ref mut a, ..)) => a,
566 (3, Junctions::X6(_, _, _, ref mut a, ..)) => a,
567 (3, Junctions::X7(_, _, _, ref mut a, ..)) => a,
568 (3, Junctions::X8(_, _, _, ref mut a, ..)) => a,
569 (4, Junctions::X5(_, _, _, _, ref mut a)) => a,
570 (4, Junctions::X6(_, _, _, _, ref mut a, ..)) => a,
571 (4, Junctions::X7(_, _, _, _, ref mut a, ..)) => a,
572 (4, Junctions::X8(_, _, _, _, ref mut a, ..)) => a,
573 (5, Junctions::X6(_, _, _, _, _, ref mut a)) => a,
574 (5, Junctions::X7(_, _, _, _, _, ref mut a, ..)) => a,
575 (5, Junctions::X8(_, _, _, _, _, ref mut a, ..)) => a,
576 (6, Junctions::X7(_, _, _, _, _, _, ref mut a)) => a,
577 (6, Junctions::X8(_, _, _, _, _, _, ref mut a, ..)) => a,
578 (7, Junctions::X8(_, _, _, _, _, _, _, ref mut a)) => a,
579 _ => return None,
580 })
581 }
582
583 pub fn iter(&self) -> JunctionsRefIterator {
585 JunctionsRefIterator { junctions: self, next: 0, back: 0 }
586 }
587
588 pub fn match_and_split(&self, prefix: &Junctions) -> Option<&Junction> {
599 if prefix.len() + 1 != self.len() {
600 return None
601 }
602 for i in 0..prefix.len() {
603 if prefix.at(i) != self.at(i) {
604 return None
605 }
606 }
607 return self.at(prefix.len())
608 }
609
610 pub fn starts_with(&self, prefix: &Junctions) -> bool {
611 prefix.len() <= self.len() && prefix.iter().zip(self.iter()).all(|(x, y)| x == y)
612 }
613}
614
615impl TryFrom<MultiLocation> for Junctions {
616 type Error = MultiLocation;
617 fn try_from(x: MultiLocation) -> result::Result<Self, MultiLocation> {
618 if x.parents > 0 {
619 Err(x)
620 } else {
621 Ok(x.interior)
622 }
623 }
624}
625
626impl<T: Into<Junction>> From<T> for Junctions {
627 fn from(x: T) -> Self {
628 Self::X1(x.into())
629 }
630}
631
632impl From<[Junction; 0]> for Junctions {
633 fn from(_: [Junction; 0]) -> Self {
634 Self::Here
635 }
636}
637
638impl From<()> for Junctions {
639 fn from(_: ()) -> Self {
640 Self::Here
641 }
642}
643
644xcm_procedural::impl_conversion_functions_for_junctions_v3!();
645
646#[cfg(test)]
647mod tests {
648 use super::{super::prelude::*, *};
649
650 #[test]
651 fn inverting_works() {
652 let context: InteriorMultiLocation = (Parachain(1000), PalletInstance(42)).into();
653 let target = (Parent, PalletInstance(69)).into();
654 let expected = (Parent, PalletInstance(42)).into();
655 let inverted = context.invert_target(&target).unwrap();
656 assert_eq!(inverted, expected);
657
658 let context: InteriorMultiLocation =
659 (Parachain(1000), PalletInstance(42), GeneralIndex(1)).into();
660 let target = (Parent, Parent, PalletInstance(69), GeneralIndex(2)).into();
661 let expected = (Parent, Parent, PalletInstance(42), GeneralIndex(1)).into();
662 let inverted = context.invert_target(&target).unwrap();
663 assert_eq!(inverted, expected);
664 }
665
666 #[test]
667 fn relative_to_works() {
668 use Junctions::*;
669 use NetworkId::*;
670 assert_eq!(X1(Polkadot.into()).relative_to(&X1(Kusama.into())), (Parent, Polkadot).into());
671 let base = X3(Kusama.into(), Parachain(1), PalletInstance(1));
672
673 assert_eq!(Here.relative_to(&base), (Parent, Parent, Parent).into());
675 assert_eq!(X1(Kusama.into()).relative_to(&base), (Parent, Parent).into());
676 assert_eq!(X2(Kusama.into(), Parachain(1)).relative_to(&base), (Parent,).into());
677 assert_eq!(
678 X3(Kusama.into(), Parachain(1), PalletInstance(1)).relative_to(&base),
679 Here.into()
680 );
681
682 assert_eq!(
684 X1(Polkadot.into()).relative_to(&base),
685 (Parent, Parent, Parent, Polkadot).into()
686 );
687 assert_eq!(
688 X2(Kusama.into(), Parachain(2)).relative_to(&base),
689 (Parent, Parent, Parachain(2)).into()
690 );
691 assert_eq!(
692 X3(Kusama.into(), Parachain(1), PalletInstance(2)).relative_to(&base),
693 (Parent, PalletInstance(2)).into()
694 );
695 assert_eq!(
696 X4(Kusama.into(), Parachain(1), PalletInstance(1), [1u8; 32].into()).relative_to(&base),
697 ([1u8; 32],).into()
698 );
699
700 assert_eq!(
702 X2(Polkadot.into(), Parachain(1)).relative_to(&base),
703 (Parent, Parent, Parent, Polkadot, Parachain(1)).into()
704 );
705 assert_eq!(
706 X3(Kusama.into(), Parachain(2), PalletInstance(1)).relative_to(&base),
707 (Parent, Parent, Parachain(2), PalletInstance(1)).into()
708 );
709 assert_eq!(
710 X4(Kusama.into(), Parachain(1), PalletInstance(2), [1u8; 32].into()).relative_to(&base),
711 (Parent, PalletInstance(2), [1u8; 32]).into()
712 );
713 assert_eq!(
714 X5(Kusama.into(), Parachain(1), PalletInstance(1), [1u8; 32].into(), 1u128.into())
715 .relative_to(&base),
716 ([1u8; 32], 1u128).into()
717 );
718 }
719
720 #[test]
721 fn global_consensus_works() {
722 use Junctions::*;
723 use NetworkId::*;
724 assert_eq!(X1(Polkadot.into()).global_consensus(), Ok(Polkadot));
725 assert_eq!(X2(Kusama.into(), 1u64.into()).global_consensus(), Ok(Kusama));
726 assert_eq!(Here.global_consensus(), Err(()));
727 assert_eq!(X1(1u64.into()).global_consensus(), Err(()));
728 assert_eq!(X2(1u64.into(), Kusama.into()).global_consensus(), Err(()));
729 }
730
731 #[test]
732 fn test_conversion() {
733 use super::{Junction::*, Junctions::*, NetworkId::*};
734 let x: Junctions = GlobalConsensus(Polkadot).into();
735 assert_eq!(x, X1(GlobalConsensus(Polkadot)));
736 let x: Junctions = Polkadot.into();
737 assert_eq!(x, X1(GlobalConsensus(Polkadot)));
738 let x: Junctions = (Polkadot, Kusama).into();
739 assert_eq!(x, X2(GlobalConsensus(Polkadot), GlobalConsensus(Kusama)));
740 }
741}