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

Add matches_prefix function to MultiLocation and Junctions #4827

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions xcm/src/v0/multi_location.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,31 @@ impl MultiLocation {
return self.at(prefix.len())
}

/// Returns whether `self` begins with or is equal to `prefix`.
///
/// # Example
/// ```rust
/// # use xcm::v0::{Junction::*, MultiLocation::*};
/// # fn main() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// # fn main() {

Rust does this automatically

/// let m = X4(Parent, PalletInstance(3), OnlyChild, OnlyChild);
/// assert!(m.matches_prefix(&X2(Parent, PalletInstance(3))));
/// assert!(m.matches_prefix(&m));
/// assert!(!m.matches_prefix(&X2(Parent, GeneralIndex(99))));
/// assert!(!m.matches_prefix(&X1(PalletInstance(3))));
/// # }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// # }

/// ```
pub fn matches_prefix(&self, prefix: &MultiLocation) -> bool {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub fn matches_prefix(&self, prefix: &MultiLocation) -> bool {
pub fn starts_with(&self, prefix: &MultiLocation) -> bool {

Sounds more like the other methods available in rust

if self.len() < prefix.len() {
return false
}
for i in 0..prefix.len() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
for i in 0..prefix.len() {
prefix.iter().zip(self.iter()).all(|l, r| l == r)

This could be used to replace the rest of the function

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's how I implemented it in Cumulus, but here I figured I'd keep to the imperative style of match_and_split 😄
Can definitely do.

if prefix.at(i) != self.at(i) {
return false
}
}
true
}

/// 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
48 changes: 47 additions & 1 deletion xcm/src/v1/multilocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,26 @@ 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};
/// # fn main() {
/// let m = MultiLocation::new(1, X3(PalletInstance(3), OnlyChild, OnlyChild));
/// assert!(m.matches_prefix(&MultiLocation::new(1, X1(PalletInstance(3)))));
/// assert!(!m.matches_prefix(&MultiLocation::new(1, X1(GeneralIndex(99)))));
/// assert!(!m.matches_prefix(&MultiLocation::new(0, X1(PalletInstance(3)))));
/// # }
/// ```
pub fn matches_prefix(&self, prefix: &MultiLocation) -> bool {
if self.parents != prefix.parents {
return false
}
self.interior.matches_prefix(&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 @@ -809,7 +829,33 @@ impl Junctions {
return None
}
}
return self.at(prefix.len())
self.at(prefix.len())
}

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

Expand Down