use std::str::FromStr;
use super::Result;
use crate::{ParseValueError, Value};
fn clean_input(s: &str, leading: &str) -> String {
let mut input = String::with_capacity(s.len());
input.extend(s.chars().filter(|&c| c != '_'));
input.trim_start_matches(leading).to_owned()
}
impl Value {
pub fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseValueError> {
u64::from_str_radix(src, radix)
.map(Self::UnsignedInt)
.or_else(|_| u128::from_str_radix(src, radix).map(Self::UnsignedBigInt))
.or_else(|_| i64::from_str_radix(src, radix).map(Self::SignedInt))
.or_else(|_| i128::from_str_radix(src, radix).map(Self::SignedBigInt))
.map_err(|_| ParseValueError::Radix(src.to_owned(), radix))
}
pub fn parse_binary(s: &str) -> Result<Self, ParseValueError> {
Value::from_str_radix(&clean_input(s, "0b"), 2)
}
pub fn parse_octal(s: &str) -> Result<Self, ParseValueError> {
Value::from_str_radix(&clean_input(s, "0o"), 8)
}
pub fn parse_decimal(s: &str) -> Result<Self, ParseValueError> {
Value::from_str_radix(&clean_input(s, "0d"), 10)
}
pub fn parse_hex(s: &str) -> Result<Self, ParseValueError> {
Value::from_str_radix(&clean_input(s, "0x"), 16)
}
}
impl FromStr for Value {
type Err = ParseValueError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
s.parse::<u64>()
.map(Self::UnsignedInt)
.or_else(|_| s.parse::<u128>().map(Self::UnsignedBigInt))
.or_else(|_| s.parse::<i64>().map(Self::SignedInt))
.or_else(|_| s.parse::<i128>().map(Self::SignedBigInt))
.or_else(|_| s.parse::<f64>().map(Self::Float))
.map_err(|_| ParseValueError::Simple(s.to_owned()))
}
}