Skip to content

Commit

Permalink
rebase daan/api
Browse files Browse the repository at this point in the history
  • Loading branch information
Daanvdplas committed Sep 13, 2024
2 parents 497b2f7 + 7bbc04c commit ca71ec6
Show file tree
Hide file tree
Showing 15 changed files with 598 additions and 707 deletions.
21 changes: 21 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 7 additions & 4 deletions extension/src/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ pub trait Readable {
/// Trait for fallible conversion of a value based on additional information available from the
/// environment.
pub trait Converter {
/// The type returned in the event of a conversion error.
/// The error type returned when conversion fails.
type Error;
/// The type of value to be converted.
type Source;
Expand All @@ -173,7 +173,7 @@ pub trait Converter {
/// A default converter, for converting (encoding) from some type into a byte array.
pub struct DefaultConverter<T>(PhantomData<T>);
impl<T: Into<Vec<u8>>> Converter for DefaultConverter<T> {
/// The type returned in the event of a conversion error.
/// The error type returned when conversion fails.
type Error = DispatchError;
/// The type of value to be converted.
type Source = T;
Expand Down Expand Up @@ -476,7 +476,7 @@ mod tests {
Ok(Converging(0))
));
// Check if the contract environment buffer is written correctly.
assert_eq!(env.buffer, UppercaseConverter::try_convert(expected, &env).unwrap());
assert_eq!(Ok(&env.buffer), UppercaseConverter::try_convert(expected, &env).as_ref());
}

#[test]
Expand Down Expand Up @@ -552,6 +552,9 @@ mod tests {
fn default_conversion_works() {
let env = MockEnvironment::default();
let source = "pop".to_string();
assert_eq!(DefaultConverter::try_convert(source.clone(), &env).unwrap(), source.as_bytes());
assert_eq!(
DefaultConverter::try_convert(source.clone(), &env),
Ok(source.as_bytes().into())
);
}
}
107 changes: 65 additions & 42 deletions pallets/api/src/extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ impl<Source: Debug, Target: TryFrom<(Source, u8), Error = DispatchError> + Debug
/// - `value` - The value to be converted.
/// - `env` - The current execution environment.
fn try_convert(value: Self::Source, env: &impl Environment) -> Result<Self::Target> {
// Defer to supplied versioned result conversion type
// Defer to supplied versioned result conversion type.
let version = version(env);
log::debug!(target: Self::LOG_TARGET, "versioned result converter: result={value:?}, version={version}");
let converted: Target = (value, version).try_into()?;
Expand Down Expand Up @@ -163,12 +163,16 @@ mod tests {

#[test]
fn prepender_works() {
let func = 0;
let version = 1;
let module = 2;
let index = 3;
let env = MockEnvironment {
func_id: u16::from_le_bytes([1, 2]),
ext_id: u16::from_le_bytes([3, 4]),
func_id: u16::from_le_bytes([func, version]),
ext_id: u16::from_le_bytes([module, index]),
};
assert_eq!(Prepender::process(vec![0u8], &env), vec![2, 3, 4, 0]);
assert_eq!(Prepender::process(vec![0u8, 5, 10], &env), vec![2, 3, 4, 0, 5, 10]);
let data = 42;
assert_eq!(Prepender::process(vec![data], &env), vec![version, module, index, data]);
}

#[test]
Expand Down Expand Up @@ -199,9 +203,8 @@ mod tests {
));
}

#[test]
fn versioned_error_converter_works() {
use super::RetVal::Converging;
mod versioned_error {
use super::{RetVal::Converging, *};

// Mock versioned error.
#[derive(Debug)]
Expand Down Expand Up @@ -239,36 +242,41 @@ mod tests {
}
}

// Because `Retval` does not implement the `Debug` trait the success and error test cases
// are separated.
for (version, error, expected_result) in vec![
(0, BadOrigin, 1),
(0, CannotLookup, 100),
(1, BadOrigin, 2),
(1, CannotLookup, 200),
] {
let env = MockEnvironment { func_id: u16::from_le_bytes([0, version]), ext_id: 0u16 };
// Again, due to missing `Debug` trait the result has to be unwrapped.
let Ok(Converging(result)) =
VersionedErrorConverter::<VersionedError>::convert(error, &env)
else {
panic!("should not happen")
};
assert_eq!(result, expected_result);
#[test]
fn versioned_error_converter_works() {
for (version, error, expected_result) in vec![
(0, BadOrigin, 1),
(0, Other("test"), 100),
(1, BadOrigin, 2),
(1, Other("test"), 200),
] {
let env =
MockEnvironment { func_id: u16::from_le_bytes([0, version]), ext_id: 0u16 };
// Because `Retval` does not implement the `Debug` trait the result has to be
// unwrapped.
let Ok(Converging(result)) =
VersionedErrorConverter::<VersionedError>::convert(error, &env)
else {
panic!("should not happen")
};
assert_eq!(result, expected_result);
}
}

// Error case.
let env = MockEnvironment { func_id: u16::from_le_bytes([0, 2]), ext_id: 0u16 };
let result = VersionedErrorConverter::<VersionedError>::convert(BadOrigin, &env)
.err()
.unwrap(); // Again, can't use `unwrap_err()` due to missing `Debug` trait.
assert_eq!(result, Other("DecodingFailed"));
#[test]
fn versioned_error_converter_fails_when_invalid_version() {
let version = 2;
let env = MockEnvironment { func_id: u16::from_le_bytes([0, version]), ext_id: 0u16 };
let result = VersionedErrorConverter::<VersionedError>::convert(BadOrigin, &env).err();
assert_eq!(result, Some(Other("DecodingFailed")));
}
}

#[test]
fn versioned_result_converter_works() {
mod versioned_result {
use VersionedRuntimeResult::{V0, V1};

use super::*;

// Mock versioned runtime result.
#[derive(Debug, PartialEq)]
pub enum VersionedRuntimeResult {
Expand All @@ -282,6 +290,7 @@ mod tests {
// Mock conversion based on result and version.
fn try_from(value: (u8, u8)) -> Result<Self> {
let (result, version) = value;
// Per version there is a specific upper bound allowed.
match version {
0 if result <= 50 => Ok(V0(result)),
0 if result > 50 => Ok(V0(50)),
Expand All @@ -292,17 +301,31 @@ mod tests {
}
}

for (version, value, expected_result) in vec![
(0, 10, Ok(V0(10))),
(0, 100, Ok(V0(50))),
(1, 10, Ok(V1(10))),
(1, 100, Ok(V1(100))),
(2, 10, Err(Other("DecodingFailed"))),
] {
let env = MockEnvironment { func_id: u16::from_le_bytes([0, version]), ext_id: 0u16 };
#[test]
fn versioned_result_converter_works() {
for (version, value, expected_result) in vec![
(0, 10, Ok(V0(10))),
// `V0` has 50 as upper bound and therefore caps the value.
(0, 100, Ok(V0(50))),
(1, 10, Ok(V1(10))),
// Different upper bound for `V1`.
(1, 100, Ok(V1(100))),
] {
let env =
MockEnvironment { func_id: u16::from_le_bytes([0, version]), ext_id: 0u16 };
let result = VersionedResultConverter::<u8, VersionedRuntimeResult>::try_convert(
value, &env,
);
assert_eq!(result, expected_result);
}
}

#[test]
fn versioned_result_converter_fails_when_invalid_version() {
let env = MockEnvironment { func_id: u16::from_le_bytes([0, 2]), ext_id: 0u16 };
let result =
VersionedResultConverter::<u8, VersionedRuntimeResult>::try_convert(value, &env);
assert_eq!(result, expected_result);
VersionedResultConverter::<u8, VersionedRuntimeResult>::try_convert(10, &env).err();
assert_eq!(result, Some(Other("DecodingFailed")));
}
}

Expand Down
Loading

0 comments on commit ca71ec6

Please sign in to comment.