mirror of
https://github.com/fluencelabs/examples
synced 2025-04-25 10:42:16 +00:00
u256 math module example
This commit is contained in:
parent
f5e6c88270
commit
8dd889b333
@ -15,5 +15,7 @@ path = "src/main.rs"
|
|||||||
fluence = "0.6.9"
|
fluence = "0.6.9"
|
||||||
ethnum = "1.0.3"
|
ethnum = "1.0.3"
|
||||||
|
|
||||||
|
thiserror = "1.0.25"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
fluence-test = "0.1.9"
|
fluence-test = "0.1.9"
|
||||||
|
28
math/src/errors.rs
Normal file
28
math/src/errors.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021 Fluence Labs Limited
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use thiserror::Error as ThisError;
|
||||||
|
|
||||||
|
use std::num::ParseIntError;
|
||||||
|
|
||||||
|
#[derive(ThisError, Debug)]
|
||||||
|
pub enum U256Error {
|
||||||
|
#[error("an overflow is occured")]
|
||||||
|
U256Overflow,
|
||||||
|
|
||||||
|
#[error("{0}")]
|
||||||
|
ParseError(#[from] ParseIntError),
|
||||||
|
}
|
130
math/src/main.rs
130
math/src/main.rs
@ -16,7 +16,24 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use ethnum::*;
|
#![warn(rust_2018_idioms)]
|
||||||
|
#![deny(
|
||||||
|
dead_code,
|
||||||
|
nonstandard_style,
|
||||||
|
unused_imports,
|
||||||
|
unused_mut,
|
||||||
|
unused_variables,
|
||||||
|
unused_unsafe,
|
||||||
|
unreachable_patterns
|
||||||
|
)]
|
||||||
|
|
||||||
|
mod errors;
|
||||||
|
mod result;
|
||||||
|
|
||||||
|
use errors::U256Error;
|
||||||
|
use result::U256Result;
|
||||||
|
|
||||||
|
use ethnum::u256;
|
||||||
use fluence::marine;
|
use fluence::marine;
|
||||||
use fluence::module_manifest;
|
use fluence::module_manifest;
|
||||||
|
|
||||||
@ -24,104 +41,69 @@ module_manifest!();
|
|||||||
|
|
||||||
pub fn main() {}
|
pub fn main() {}
|
||||||
|
|
||||||
/// Result<u256, MathError: ToPrimitive + FromPrimitive> like
|
use std::convert::identity;
|
||||||
#[marine]
|
use U256Error::U256Overflow;
|
||||||
pub struct MathResult {
|
|
||||||
/// u256 string representation
|
|
||||||
pub u256: String,
|
|
||||||
pub ret_code: u8,
|
|
||||||
/// error string representation
|
|
||||||
pub err_msg: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
mod math_result {
|
|
||||||
use ethnum::u256;
|
|
||||||
|
|
||||||
use crate::MathResult;
|
|
||||||
|
|
||||||
pub fn ok(ok: u256) -> MathResult {
|
|
||||||
MathResult {
|
|
||||||
u256: ok.to_string(),
|
|
||||||
ret_code: 0,
|
|
||||||
err_msg: Default::default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn err(err: &str) -> MathResult {
|
|
||||||
MathResult {
|
|
||||||
u256: Default::default(),
|
|
||||||
ret_code: 1,
|
|
||||||
err_msg: err.to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
use math_result::{err, ok};
|
|
||||||
|
|
||||||
/// adds 2 256 bits integers (ETH compatible)
|
/// adds 2 256 bits integers (ETH compatible)
|
||||||
/// return number or error (failed to parse input or overflow of output)
|
/// return number or error (failed to parse input or overflow of output)
|
||||||
#[marine]
|
#[marine]
|
||||||
pub fn add_u256(number_1: String, number_2: String) -> MathResult {
|
pub fn add_u256(lhs: String, rhs: String) -> U256Result {
|
||||||
let number_1 = number_1.parse::<u256>();
|
add_u256_impl(lhs, rhs)
|
||||||
let number_2 = number_2.parse::<u256>();
|
.map_err(Into::into)
|
||||||
if let (Ok(number_1), Ok(number_2)) = (number_1, number_2) {
|
.unwrap_or_else(identity)
|
||||||
let number = number_1.checked_add(number_2);
|
|
||||||
if let Some(number) = number {
|
|
||||||
return ok(number);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return err("Overflow");
|
pub fn add_u256_impl(lhs: String, rhs: String) -> Result<U256Result, U256Error> {
|
||||||
}
|
let lhs = lhs.parse::<u256>()?;
|
||||||
|
let rhs = rhs.parse::<u256>()?;
|
||||||
|
let result = lhs.checked_add(rhs).ok_or_else(|| U256Overflow)?;
|
||||||
|
|
||||||
err("InputNonAU256Number")
|
Ok(U256Result::from_u256(result))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[marine]
|
#[marine]
|
||||||
pub fn sub_u256(number_1: String, number_2: String) -> MathResult {
|
pub fn sub_u256(lhs: String, rhs: String) -> U256Result {
|
||||||
let number_1 = number_1.parse::<u256>();
|
sub_u256_impl(lhs, rhs)
|
||||||
let number_2 = number_2.parse::<u256>();
|
.map_err(Into::into)
|
||||||
if let (Ok(number_1), Ok(number_2)) = (number_1, number_2) {
|
.unwrap_or_else(identity)
|
||||||
let number = number_1.checked_sub(number_2);
|
|
||||||
if let Some(number) = number {
|
|
||||||
return ok(number);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return err("Underflow");
|
pub fn sub_u256_impl(lhs: String, rhs: String) -> Result<U256Result, U256Error> {
|
||||||
}
|
let lhs = lhs.parse::<u256>()?;
|
||||||
|
let rhs = rhs.parse::<u256>()?;
|
||||||
|
let result = lhs.checked_sub(rhs).ok_or_else(|| U256Overflow)?;
|
||||||
|
|
||||||
err("InputNonAU256Number")
|
Ok(U256Result::from_u256(result))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[marine]
|
#[marine]
|
||||||
pub fn mul_u256(number_1: String, number_2: String) -> MathResult {
|
pub fn mul_u256(lhs: String, rhs: String) -> U256Result {
|
||||||
let number_1 = number_1.parse::<u256>();
|
mul_u256_impl(lhs, rhs)
|
||||||
let number_2 = number_2.parse::<u256>();
|
.map_err(Into::into)
|
||||||
if let (Ok(number_1), Ok(number_2)) = (number_1, number_2) {
|
.unwrap_or_else(identity)
|
||||||
let number = number_1.checked_mul(number_2);
|
|
||||||
if let Some(number) = number {
|
|
||||||
return ok(number);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return err("Overflow");
|
pub fn mul_u256_impl(lhs: String, rhs: String) -> Result<U256Result, U256Error> {
|
||||||
}
|
let lhs = lhs.parse::<u256>()?;
|
||||||
|
let rhs = rhs.parse::<u256>()?;
|
||||||
|
let result = lhs.checked_mul(rhs).ok_or_else(|| U256Overflow)?;
|
||||||
|
|
||||||
err("InputNonAU256Number")
|
Ok(U256Result::from_u256(result))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[marine]
|
#[marine]
|
||||||
pub fn div_u256(number_1: String, number_2: String) -> MathResult {
|
pub fn div_u256(lhs: String, rhs: String) -> U256Result {
|
||||||
let number_1 = number_1.parse::<u256>();
|
div_u256_impl(lhs, rhs)
|
||||||
let number_2 = number_2.parse::<u256>();
|
.map_err(Into::into)
|
||||||
if let (Ok(number_1), Ok(number_2)) = (number_1, number_2) {
|
.unwrap_or_else(identity)
|
||||||
let number = number_1.checked_div(number_2);
|
|
||||||
if let Some(number) = number {
|
|
||||||
return ok(number);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return err("DivisionByZero");
|
pub fn div_u256_impl(lhs: String, rhs: String) -> Result<U256Result, U256Error> {
|
||||||
}
|
let lhs = lhs.parse::<u256>()?;
|
||||||
|
let rhs = rhs.parse::<u256>()?;
|
||||||
|
let result = lhs.checked_div(rhs).ok_or_else(|| U256Overflow)?;
|
||||||
|
|
||||||
err("InputNonAU256Number")
|
Ok(U256Result::from_u256(result))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
55
math/src/result.rs
Normal file
55
math/src/result.rs
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021 Fluence Labs Limited
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use crate::errors::U256Error;
|
||||||
|
|
||||||
|
use ethnum::u256;
|
||||||
|
use fluence::marine;
|
||||||
|
|
||||||
|
#[marine]
|
||||||
|
#[derive(Default, Debug)]
|
||||||
|
pub struct U256Result {
|
||||||
|
/// u256 string representation
|
||||||
|
pub value: String,
|
||||||
|
pub ret_code: u8,
|
||||||
|
/// contains error as a string
|
||||||
|
pub err_msg: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl U256Result {
|
||||||
|
pub(crate) fn from_u256(value: u256) -> Self {
|
||||||
|
Self {
|
||||||
|
value: value.to_string(),
|
||||||
|
ret_code: 0, // 0 means success
|
||||||
|
err_msg: <_>::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<U256Error> for U256Result {
|
||||||
|
fn from(e: U256Error) -> Self {
|
||||||
|
let ret_code = match e {
|
||||||
|
U256Error::ParseError(_) => 1,
|
||||||
|
U256Error::U256Overflow => 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
Self {
|
||||||
|
ret_code,
|
||||||
|
err_msg: e.to_string(),
|
||||||
|
..<_>::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user