Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
Add starts_with function to MultiLocation and Junctions (#4835)
Browse files Browse the repository at this point in the history
* add matches_prefix function to MultiLocation and Junctions

* rename matches_prefix to starts_with

* remove unnecessary main in doc comment

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* Make use of starts_with in match_and_split

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
Co-authored-by: Keith Yeung <kungfukeith11@gmail.com>
  • Loading branch information
3 people authored Feb 10, 2022
1 parent 0dcdf44 commit e640d82
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 12 deletions.
25 changes: 19 additions & 6 deletions xcm/src/v0/multi_location.rs
Original file line number Diff line number Diff line change
Expand Up @@ -356,17 +356,30 @@ impl MultiLocation {
/// # }
/// ```
pub fn match_and_split(&self, prefix: &MultiLocation) -> Option<&Junction> {
if prefix.len() + 1 != self.len() {
if prefix.len() + 1 != self.len() || !self.starts_with(prefix) {
return None
}
for i in 0..prefix.len() {
if prefix.at(i) != self.at(i) {
return None
}
}
return self.at(prefix.len())
}

/// Returns whether `self` begins with or is equal to `prefix`.
///
/// # Example
/// ```rust
/// # use xcm::v0::{Junction::*, MultiLocation::*};
/// let m = X4(Parent, PalletInstance(3), OnlyChild, OnlyChild);
/// assert!(m.starts_with(&X2(Parent, PalletInstance(3))));
/// assert!(m.starts_with(&m));
/// assert!(!m.starts_with(&X2(Parent, GeneralIndex(99))));
/// assert!(!m.starts_with(&X1(PalletInstance(3))));
/// ```
pub fn starts_with(&self, prefix: &MultiLocation) -> bool {
if self.len() < prefix.len() {
return false
}
prefix.iter().zip(self.iter()).all(|(l, r)| l == r)
}

/// Mutates `self`, suffixing it with `new`. Returns `Err` in case of overflow.
pub fn push(&mut self, new: Junction) -> result::Result<(), ()> {
let mut n = MultiLocation::Null;
Expand Down
44 changes: 38 additions & 6 deletions xcm/src/v1/multilocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,24 @@ impl MultiLocation {
self.interior.match_and_split(&prefix.interior)
}

/// Returns whether `self` has the same number of parents as `prefix` and its junctions begins
/// with the junctions of `prefix`.
///
/// # Example
/// ```rust
/// # use xcm::v1::{Junctions::*, Junction::*, MultiLocation};
/// let m = MultiLocation::new(1, X3(PalletInstance(3), OnlyChild, OnlyChild));
/// assert!(m.starts_with(&MultiLocation::new(1, X1(PalletInstance(3)))));
/// assert!(!m.starts_with(&MultiLocation::new(1, X1(GeneralIndex(99)))));
/// assert!(!m.starts_with(&MultiLocation::new(0, X1(PalletInstance(3)))));
/// ```
pub fn starts_with(&self, prefix: &MultiLocation) -> bool {
if self.parents != prefix.parents {
return false
}
self.interior.starts_with(&prefix.interior)
}

/// Mutate `self` so that it is suffixed with `suffix`.
///
/// Does not modify `self` and returns `Err` with `suffix` in case of overflow.
Expand Down Expand Up @@ -816,15 +834,29 @@ impl Junctions {
/// # }
/// ```
pub fn match_and_split(&self, prefix: &Junctions) -> Option<&Junction> {
if prefix.len() + 1 != self.len() {
if prefix.len() + 1 != self.len() || !self.starts_with(prefix) {
return None
}
for i in 0..prefix.len() {
if prefix.at(i) != self.at(i) {
return None
}
self.at(prefix.len())
}

/// Returns whether `self` begins with or is equal to `prefix`.
///
/// # Example
/// ```rust
/// # use xcm::v1::{Junctions::*, Junction::*};
/// let mut j = X3(Parachain(2), PalletInstance(3), OnlyChild);
/// assert!(j.starts_with(&X2(Parachain(2), PalletInstance(3))));
/// assert!(j.starts_with(&j));
/// assert!(j.starts_with(&X1(Parachain(2))));
/// assert!(!j.starts_with(&X1(Parachain(999))));
/// assert!(!j.starts_with(&X4(Parachain(2), PalletInstance(3), OnlyChild, OnlyChild)));
/// ```
pub fn starts_with(&self, prefix: &Junctions) -> bool {
if self.len() < prefix.len() {
return false
}
return self.at(prefix.len())
prefix.iter().zip(self.iter()).all(|(l, r)| l == r)
}
}

Expand Down

0 comments on commit e640d82

Please sign in to comment.