Skip to content

Commit

Permalink
Implement decoding of floats
Browse files Browse the repository at this point in the history
Fixes #5, supersedes #6
  • Loading branch information
tailhook committed Mar 14, 2023
1 parent 0cecaa8 commit 6f3365d
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 1 deletion.
4 changes: 4 additions & 0 deletions derive/tests/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ struct Scalars {
#[knuffel(child, unwrap(argument))]
u64: u64,
#[knuffel(child, unwrap(argument))]
f64: f64,
#[knuffel(child, unwrap(argument))]
path: PathBuf,
#[knuffel(child, unwrap(argument))]
boolean: bool,
Expand All @@ -27,12 +29,14 @@ fn parse_enum() {
parse::<Scalars>(r#"
str "hello"
u64 1234
f64 16.125e+1
path "/hello/world"
boolean true
"#),
Scalars {
str: "hello".into(),
u64: 1234,
f64: 161.25,
path: PathBuf::from("/hello/world"),
boolean: true,
});
Expand Down
8 changes: 8 additions & 0 deletions src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@ pub enum BuiltinType {
Usize,
/// `isize`: platform-dependent signed integer type
Isize,
/// `f32`: 32-bit floating point number
F32,
/// `f64`: 64-bit floating point number
F64,
/// `base64` denotes binary bytes type encoded using base64 encoding
Base64,
}
Expand Down Expand Up @@ -198,6 +202,8 @@ impl BuiltinType {
I64 => "i64",
Usize => "usize",
Isize => "isize",
F32 => "f32",
F64 => "f64",
Base64 => "base64",
}
}
Expand Down Expand Up @@ -250,6 +256,8 @@ impl FromStr for BuiltinType {
"i32" => Ok(I32),
"u64" => Ok(U64),
"i64" => Ok(I64),
"f32" => Ok(F32),
"f64" => Ok(F64),
"base64" => Ok(Base64),
_ => Err(())
}
Expand Down
55 changes: 54 additions & 1 deletion src/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::str::FromStr;
use std::path::PathBuf;
use std::default::Default;

use crate::ast::{Literal, Integer, Radix, TypeName, BuiltinType};
use crate::ast::{Literal, Integer, Decimal, Radix, TypeName, BuiltinType};
use crate::decode::{Context, Kind};
use crate::errors::{DecodeError, ExpectedType};
use crate::span::{Spanned};
Expand Down Expand Up @@ -75,6 +75,59 @@ impl_integer!(u64, U64);
impl_integer!(isize, Isize);
impl_integer!(usize, Usize);

macro_rules! impl_float {
($typ: ident, $marker: ident) => {
impl TryFrom<&Decimal> for $typ {
type Error = <$typ as FromStr>::Err;
fn try_from(val: &Decimal) -> Result<$typ, <$typ as FromStr>::Err>
{
<$typ>::from_str(&val.0)
}
}

impl<S: ErrorSpan> DecodeScalar<S> for $typ {
fn raw_decode(val: &Spanned<Literal, S>, ctx: &mut Context<S>)
-> Result<$typ, DecodeError<S>>
{
match &**val {
Literal::Decimal(ref value) => {
match value.try_into() {
Ok(val) => Ok(val),
Err(e) => {
ctx.emit_error(DecodeError::conversion(val, e));
Ok(0.0)
}
}
}
_ => {
ctx.emit_error(DecodeError::scalar_kind(
Kind::String, val));
Ok(0.0)
}
}
}
fn type_check(type_name: &Option<Spanned<TypeName, S>>,
ctx: &mut Context<S>)
{
if let Some(typ) = type_name {
if typ.as_builtin() != Some(&BuiltinType::$marker) {
ctx.emit_error(DecodeError::TypeName {
span: typ.span().clone(),
found: Some(typ.value.clone()),
expected: ExpectedType::optional(
BuiltinType::$marker),
rust_type: stringify!($typ),
});
}
}
}
}
}
}

impl_float!(f32, F32);
impl_float!(f64, F64);

impl<S: ErrorSpan> DecodeScalar<S> for String {
fn raw_decode(val: &Spanned<Literal, S>, ctx: &mut Context<S>)
-> Result<String, DecodeError<S>>
Expand Down

0 comments on commit 6f3365d

Please sign in to comment.