Repository: paritytech/substrate
File: primitives/runtime/src/traits.rs (Rust)

Code before:
	pub type MorphWithUpperLimit<L: TypedGet, M>: TryMorph = |r: L::Type| -> Result<L::Type, ()> {
		M::try_morph(r).map(|m| m.min(L::get()))
	} where L::Type: Ord, M: TryMorph<L::Type, Outcome = L::Type>;
}

/// Infallible conversion trait. Generic over both source and destination types.
pub trait Convert<A, B> {
	/// Make conversion.
	fn convert(a: A) -> B;
}

/// Fallible conversion trait returning a Result. Generic over both source and destination types.
pub trait TryConvert<A, B> {
	/// Attempt the conversion and return the input value in the error case.
	fn try_convert(a: A) -> Result<B, A>;
}

/// Reversing infallible conversion trait. Generic over both source and destination types.
///
/// This specifically reverses the conversion.
pub trait ConvertBack<A, B>: Convert<A, B> {
	/// Make conversion back.
	fn convert_back(b: B) -> A;
}

/// Fallible conversion trait returning a Result. Generic over both source and destination types.
pub trait TryConvertBack<A, B>: TryConvert<A, B> {
	/// Attempt to reverse the conversion and return the input value in the error case.
	fn try_convert_back(b: B) -> Result<A, B>;
}

impl<A, B: Default> Convert<A, B> for () {
	fn convert(_: A) -> B {
		Default::default()
	}
}

#[impl_trait_for_tuples::impl_for_tuples(30)]
impl<A, B> TryConvert<A, B> for Tuple {
	fn try_convert(a: A) -> Result<B, A> {
		for_tuples!( #(
			let a = match Tuple::try_convert(a) {
				Ok(b) => return Ok(b),
				Err(a) => a,
			};
		)* );
		Err(a)
	}
}

#[impl_trait_for_tuples::impl_for_tuples(30)]

Review comment (suggestion):
```suggestion
/// Fallible conversion trait returning a [Result]. Generic over both source and destination types.
```

Code after:
	pub type MorphWithUpperLimit<L: TypedGet, M>: TryMorph = |r: L::Type| -> Result<L::Type, ()> {
		M::try_morph(r).map(|m| m.min(L::get()))
	} where L::Type: Ord, M: TryMorph<L::Type, Outcome = L::Type>;
}

/// Infallible conversion trait. Generic over both source and destination types.
pub trait Convert<A, B> {
	/// Make conversion.
	fn convert(a: A) -> B;
}

impl<A, B: Default> Convert<A, B> for () {
	fn convert(_: A) -> B {
		Default::default()
	}
}

/// Reversing infallible conversion trait. Generic over both source and destination types.
///
/// This specifically reverses the conversion.
pub trait ConvertBack<A, B>: Convert<A, B> {
	/// Make conversion back.
	fn convert_back(b: B) -> A;
}

/// Fallible conversion trait returning an [Option]. Generic over both source and destination types.
pub trait MaybeConvert<A, B> {
	/// Attempt to make conversion.
	fn maybe_convert(a: A) -> Option<B>;
}

#[impl_trait_for_tuples::impl_for_tuples(30)]
impl<A: Clone, B> MaybeConvert<A, B> for Tuple {
	fn maybe_convert(a: A) -> Option<B> {
		for_tuples!( #(
			match Tuple::maybe_convert(a.clone()) {
				Some(b) => return Some(b),
				None => {},
			}
		)* );
		None
	}
}

/// Reversing fallible conversion trait returning an [Option]. Generic over both source and
/// destination types.
pub trait MaybeConvertBack<A, B>: MaybeConvert<A, B> {
	/// Attempt to make conversion back.
	fn maybe_convert_back(b: B) -> Option<A>;
}