use core::str::FromStr;
use rust_decimal::prelude::*;
use crate::core::error2::Error;
use crate::core::error2::Result;
pub fn string_to_number<T>(input: &str) -> Result<T>
where
T: std::str::FromStr,
<T as FromStr>::Err: std::fmt::Display,
{
let result = input.trim().replace('_', "").parse::<T>().map_err(|e| {
let msg = format!("Parse `{}` to number failed", input);
Error::throw(msg, Some(e.to_string()))
})?;
Ok(result)
}
pub fn string_to_decimal(str: &str) -> Result<Decimal> {
Decimal::from_str(&remove_trailing_zeros(str)).map_err(|e| {
let msg = format!("Parse `{}` to decimal failed", str);
Error::throw(msg, Some(e.to_string()))
})
}
pub fn remove_trailing_zeros(input: &str) -> String {
let trimmed: String = input
.chars()
.rev()
.skip_while(|&c| c == '0') .collect::<String>()
.chars()
.rev() .collect();
if trimmed.ends_with('.') {
return trimmed[..trimmed.len() - 1].to_string();
}
trimmed
}
pub trait ToDecimal {
fn to_decimal(&self) -> rust_decimal::Decimal;
}
impl ToDecimal for sqlx::types::BigDecimal {
fn to_decimal(&self) -> rust_decimal::Decimal {
rust_decimal::Decimal::from_str(&self.to_string()).unwrap()
}
}