use crate::no_std::*;
use core::{
fmt::{Debug, Display},
hash::Hash,
};
pub trait Amount:
Copy + Clone + Debug + Display + Send + Sync + 'static + Eq + Ord + Sized + Hash
{
}
#[derive(Debug, Error)]
pub enum AmountError {
#[error("{0}: {1}")]
Crate(&'static str, String),
#[error("the amount: {0:} exceeds the supply bounds of {1:}")]
AmountOutOfBounds(String, String),
#[error("invalid amount: {0:}")]
InvalidAmount(String),
}
pub fn to_basic_unit(value: &str, mut denomination: u32) -> String {
if denomination > 18 {
println!("illegal denomination");
return "".to_string();
}
let mut has_point: bool = false;
let mut point: usize = 0;
let mut cnt: usize = 0;
for c in value.chars() {
if c.is_ascii_digit() || c == '.' {
if c == '.' {
if has_point {
println!("duplicate decimal point");
return "".to_string();
}
if cnt == 0 {
return "0".to_string();
}
has_point = true;
point = cnt;
}
cnt += 1;
} else {
println!("illegal decimal string");
return "".to_string();
}
}
let mut value = value.to_string();
if !has_point {
value.insert(value.len(), '.');
point = value.len() - 1;
}
let mut v = value.as_bytes().to_vec();
while denomination > 0 {
if point == v.len() - 1 {
v.push(b'0');
}
v.swap(point, point + 1);
point += 1;
denomination -= 1;
}
if point < v.len() - 1 && v[point + 1] > b'5' {
v[point - 1] += 1;
}
v.truncate(point);
String::from_utf8(v).unwrap()
}
#[test]
fn test() {
let s = to_basic_unit("0.0001037910", 7);
println!("s = {}", s);
}