diff --git a/substrate/frame/support/src/origin.rs b/substrate/frame/support/src/origin.rs index 19b24fb84b..6dd38eb1b2 100644 --- a/substrate/frame/support/src/origin.rs +++ b/substrate/frame/support/src/origin.rs @@ -246,6 +246,16 @@ macro_rules! impl_outer_origin { &self.caller } + fn try_with_caller( + mut self, + f: impl FnOnce(Self::PalletsOrigin) -> Result, + ) -> Result { + match f(self.caller) { + Ok(r) => Ok(r), + Err(caller) => { self.caller = caller; Err(self) } + } + } + /// Create with system none origin and `frame-system::Config::BaseCallFilter`. fn none() -> Self { $system::RawOrigin::None.into() @@ -299,6 +309,20 @@ macro_rules! impl_outer_origin { $caller_name::system(x) } } + + impl $crate::sp_std::convert::TryFrom<$caller_name> for $system::Origin<$runtime> { + type Error = $caller_name; + fn try_from(x: $caller_name) + -> $crate::sp_std::result::Result<$system::Origin<$runtime>, $caller_name> + { + if let $caller_name::system(l) = x { + Ok(l) + } else { + Err(x) + } + } + } + impl From<$system::Origin<$runtime>> for $name { /// Convert to runtime origin: /// * root origin is built with no filter @@ -376,6 +400,22 @@ macro_rules! impl_outer_origin { } } } + + impl $crate::sp_std::convert::TryFrom< + $caller_name + > for $module::Origin < $( $generic )? $(, $module::$generic_instance )? > { + type Error = $caller_name; + fn try_from(x: $caller_name) -> $crate::sp_std::result::Result< + $module::Origin < $( $generic )? $(, $module::$generic_instance )? >, + $caller_name, + > { + if let $caller_name::[< $module $( _ $generic_instance )? >](l) = x { + Ok(l) + } else { + Err(x) + } + } + } } )* } diff --git a/substrate/frame/support/src/traits/dispatch.rs b/substrate/frame/support/src/traits/dispatch.rs index 29dbaf105a..6174238e35 100644 --- a/substrate/frame/support/src/traits/dispatch.rs +++ b/substrate/frame/support/src/traits/dispatch.rs @@ -76,6 +76,12 @@ pub trait OriginTrait: Sized { /// Get the caller. fn caller(&self) -> &Self::PalletsOrigin; + /// Do something with the caller, consuming self but returning it if the caller was unused. + fn try_with_caller( + self, + f: impl FnOnce(Self::PalletsOrigin) -> Result, + ) -> Result; + /// Create with system none origin and `frame-system::Config::BaseCallFilter`. fn none() -> Self;