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

Add starts_with function to MultiLocation and Junctions #4835

Merged
merged 5 commits into from
Feb 10, 2022
Merged
Show file tree
Hide file tree
Changes from 3 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
18 changes: 18 additions & 0 deletions xcm/src/v0/multi_location.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,24 @@ impl MultiLocation {
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
41 changes: 40 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.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)))));
/// # }
apopiak marked this conversation as resolved.
Show resolved Hide resolved
/// ```
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 @@ -824,7 +844,26 @@ 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::*};
/// 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
}
prefix.iter().zip(self.iter()).all(|(l, r)| l == r)
}
}

Expand Down