From 9bdb627d517b24dc63032be1295754be0604760a Mon Sep 17 00:00:00 2001 From: Alexander Popiak Date: Tue, 1 Feb 2022 17:33:26 +0100 Subject: [PATCH 1/4] add matches_prefix function to MultiLocation and Junctions --- xcm/src/v0/multi_location.rs | 25 +++++++++++++++++++ xcm/src/v1/multilocation.rs | 48 +++++++++++++++++++++++++++++++++++- 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/xcm/src/v0/multi_location.rs b/xcm/src/v0/multi_location.rs index 6b7438b93fa0..e45a546f3dc9 100644 --- a/xcm/src/v0/multi_location.rs +++ b/xcm/src/v0/multi_location.rs @@ -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() { + /// 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)))); + /// # } + /// ``` + pub fn matches_prefix(&self, prefix: &MultiLocation) -> bool { + if self.len() < prefix.len() { + return false + } + for i in 0..prefix.len() { + 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; diff --git a/xcm/src/v1/multilocation.rs b/xcm/src/v1/multilocation.rs index 12b507329215..e87d185e2764 100644 --- a/xcm/src/v1/multilocation.rs +++ b/xcm/src/v1/multilocation.rs @@ -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. @@ -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 } } From 8b077c46b57406822819539105d17ffbbff87ebd Mon Sep 17 00:00:00 2001 From: Alexander Popiak Date: Wed, 2 Feb 2022 16:05:52 +0100 Subject: [PATCH 2/4] rename matches_prefix to starts_with --- xcm/src/v0/multi_location.rs | 19 ++++++------------- xcm/src/v1/multilocation.rs | 31 ++++++++++++------------------- 2 files changed, 18 insertions(+), 32 deletions(-) diff --git a/xcm/src/v0/multi_location.rs b/xcm/src/v0/multi_location.rs index e45a546f3dc9..1fbd08982ab3 100644 --- a/xcm/src/v0/multi_location.rs +++ b/xcm/src/v0/multi_location.rs @@ -372,24 +372,17 @@ impl MultiLocation { /// # Example /// ```rust /// # use xcm::v0::{Junction::*, MultiLocation::*}; - /// # fn main() { /// 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)))); - /// # } + /// 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 matches_prefix(&self, prefix: &MultiLocation) -> bool { + pub fn starts_with(&self, prefix: &MultiLocation) -> bool { if self.len() < prefix.len() { return false } - for i in 0..prefix.len() { - if prefix.at(i) != self.at(i) { - return false - } - } - true + prefix.iter().zip(self.iter()).all(|(l, r)| l == r) } /// Mutates `self`, suffixing it with `new`. Returns `Err` in case of overflow. diff --git a/xcm/src/v1/multilocation.rs b/xcm/src/v1/multilocation.rs index 28735dd0eab2..bff8d27b4cff 100644 --- a/xcm/src/v1/multilocation.rs +++ b/xcm/src/v1/multilocation.rs @@ -261,16 +261,16 @@ impl MultiLocation { /// # 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))))); + /// 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 matches_prefix(&self, prefix: &MultiLocation) -> bool { + pub fn starts_with(&self, prefix: &MultiLocation) -> bool { if self.parents != prefix.parents { return false } - self.interior.matches_prefix(&prefix.interior) + self.interior.starts_with(&prefix.interior) } /// Mutate `self` so that it is suffixed with `suffix`. @@ -852,25 +852,18 @@ impl Junctions { /// # 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))); - /// # } + /// 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 matches_prefix(&self, prefix: &Junctions) -> bool { + pub fn starts_with(&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 + prefix.iter().zip(self.iter()).all(|(l, r)| l == r) } } From b5dc656e834c682aa698ea85a745af9d73747137 Mon Sep 17 00:00:00 2001 From: Alexander Popiak Date: Thu, 3 Feb 2022 16:21:07 +0100 Subject: [PATCH 3/4] remove unnecessary main in doc comment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bastian Köcher --- xcm/src/v1/multilocation.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/xcm/src/v1/multilocation.rs b/xcm/src/v1/multilocation.rs index bff8d27b4cff..00eb89df3e97 100644 --- a/xcm/src/v1/multilocation.rs +++ b/xcm/src/v1/multilocation.rs @@ -259,12 +259,10 @@ impl MultiLocation { /// # 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))))); - /// # } /// ``` pub fn starts_with(&self, prefix: &MultiLocation) -> bool { if self.parents != prefix.parents { From 07c87f9348109de961b2c0423e7814125a317948 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Fri, 4 Feb 2022 15:06:01 -0800 Subject: [PATCH 4/4] Make use of starts_with in match_and_split --- xcm/src/v0/multi_location.rs | 7 +------ xcm/src/v1/multilocation.rs | 7 +------ 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/xcm/src/v0/multi_location.rs b/xcm/src/v0/multi_location.rs index 1fbd08982ab3..0df525f06577 100644 --- a/xcm/src/v0/multi_location.rs +++ b/xcm/src/v0/multi_location.rs @@ -356,14 +356,9 @@ 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()) } diff --git a/xcm/src/v1/multilocation.rs b/xcm/src/v1/multilocation.rs index 00eb89df3e97..b02bf9d3b07a 100644 --- a/xcm/src/v1/multilocation.rs +++ b/xcm/src/v1/multilocation.rs @@ -834,14 +834,9 @@ 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()) }