Skip to content

Commit

Permalink
Add a TryFrom trait (FuelLabs#3899)
Browse files Browse the repository at this point in the history
This introduces a new trait `TryFrom` for conversions that could be
fallible, and tests it by implementing for `b256` as
`impl TryFrom<Bytes> for b256`:

```
pub trait TryFrom<T> {
    fn try_from(b: T) -> Option<Self>;
}
```
  • Loading branch information
nfurfaro authored Jan 27, 2023
1 parent 96ec475 commit 0917109
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 6 deletions.
49 changes: 49 additions & 0 deletions sway-lib-std/src/b256.sw
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
library b256;

use ::assert::assert;
use ::bytes::Bytes;
use ::convert::TryFrom;
use ::option::Option;
use ::logging::log;

impl TryFrom<Bytes> for b256 {
fn try_from(b: Bytes) -> Option<Self> {
if b.len() > 32 {
Option::None
} else {
let mut val = 0x0000000000000000000000000000000000000000000000000000000000000000;
let ptr = __addr_of(val);
b.buf.ptr().copy_to::<b256>(ptr, 1);
Option::Some(val)
}
}
}

#[test]
fn test_b256_try_from() {
let mut initial_bytes = Bytes::with_capacity(32);
let mut i = 0;
while i < 32 {
// 0x33 is 51 in decimal
initial_bytes.push(51u8);
i += 1;
}
let res = b256::try_from(initial_bytes);
let expected = 0x3333333333333333333333333333333333333333333333333333333333333333;

assert(res.unwrap() == expected);

let mut second_bytes = Bytes::with_capacity(33);
i = 0;
while i < 33 {
// 0x33 is 51 in decimal
second_bytes.push(51u8);
i += 1;
}
let res = b256::try_from(second_bytes);
assert(res.is_none());

// bytes is still available to use:
assert(second_bytes.len() == 33);
assert(second_bytes.capacity() == 33);
}
11 changes: 10 additions & 1 deletion sway-lib-std/src/convert.sw
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
//! Traits for conversions between types.
library convert;

/// Used to do value-to-value conversions while consuming the input value.
use ::option::Option;

/// Used to do value-to-value conversions.
pub trait From<T> {
fn from(b: T) -> Self;
fn into(self) -> T;
}

// TODO: return a Result when https://github.com/FuelLabs/sway/issues/610 is resolved
/// Used to attempt to do value-to-value conversions.
/// Returns Option::None if the conversion can't be performed in a lossless manner.
pub trait TryFrom<T> {
fn try_from(b: T) -> Option<Self>;
}
9 changes: 5 additions & 4 deletions sway-lib-std/src/lib.sw
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
library std;

dep convert;
dep intrinsics;
dep error_signals;
dep logging;
dep revert;
dep assert;
dep result;
dep option;
dep convert;
dep intrinsics;
dep assert;
dep alloc;
dep contract_id;
dep constants;
Expand All @@ -20,9 +20,10 @@ dep r#storage;
dep b512;
dep address;
dep identity;
dep tx;
dep vec;
dep bytes;
dep b256;
dep tx;
dep inputs;
dep outputs;
dep auth;
Expand Down
1 change: 0 additions & 1 deletion sway-lib-std/src/option.sw
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@
//! `ok_or` : `Option::ok_or`
library option;

use ::convert::From;
use ::result::Result;
use ::revert::revert;

Expand Down

0 comments on commit 0917109

Please sign in to comment.