ridstack-form 0.1.0

End-to-End Type-safe form handling for Dioxus applications
use crate::prelude::*;
use std::{
    num::{ParseFloatError, ParseIntError},
    str::ParseBoolError,
};

macro_rules! impl_int {
    ($($ty:tt),*) => {
        $(impl PrimitiveFieldValue for $ty {}
        impl FieldValue for $ty {
            type PrimitiveValue = Self;
            type ConversionError = ParseIntError;
            fn from_str(value: &str) -> Result<Self, Self::ConversionError> {
                value.parse()
            }
            fn to_primitive_field_value(&self) -> Self::PrimitiveValue {
                *self
            }


        }

        impl SealedNum for $ty{}
        impl StringValue for $ty{
        fn to_string_value(&self)->String{
            self.to_string()
        }
        }
        )*
    };
}
macro_rules! impl_float {
    ($($ty:tt),*) => {
        $(impl PrimitiveFieldValue for $ty {}
        impl FieldValue for $ty {
            type PrimitiveValue = Self;
            type ConversionError = ParseFloatError;
            fn from_str(value: &str) -> Result<Self, Self::ConversionError> {
                value.parse()
            }
            fn to_primitive_field_value(&self) -> Self::PrimitiveValue {
                *self
            }
        }

        impl SealedNum for $ty{}
        impl StringValue for $ty{

            fn to_string_value(&self)->String{
                self.to_string()
            }
        }
        )*
    };
}

impl_int!(
    u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize
);

impl_float!(f32, f64);

#[derive(thiserror::Error, Debug, Clone, derive_more::Display, PartialEq, Eq, PartialOrd, Ord)]
pub struct Infallible;
impl FieldError for Infallible {}
impl PrimitiveFieldValue for String {}
impl FieldValue for String {
    type ConversionError = Infallible;
    type PrimitiveValue = String;
    fn from_str(value: &str) -> Result<Self, Self::ConversionError> {
        Ok(value.into())
    }
    fn to_primitive_field_value(&self) -> Self::PrimitiveValue {
        self.clone()
    }
}
impl StringValue for String {
    fn to_string_value(&self) -> String {
        self.to_string()
    }
}
impl<T: PrimitiveFieldValue> PrimitiveFieldValue for Option<T> {}

impl<T: FieldValue> FieldValue for Option<T>
where
    std::option::Option<T>:
        From<std::option::Option<<T as crate::prelude::FieldValue>::PrimitiveValue>>,
{
    type PrimitiveValue = Option<T::PrimitiveValue>;
    type ConversionError = Infallible;
    fn from_str(value: &str) -> dioxus::Result<Self, Self::ConversionError> {
        Ok(T::from_str(value).ok())
    }
    fn to_primitive_field_value(&self) -> Self::PrimitiveValue {
        if let Some(val) = self {
            return Some(val.to_primitive_field_value());
        }
        return None;
    }
}
impl<T: StringValue> StringValue for Option<T> {
    fn to_string_value(&self) -> String {
        self.as_ref()
            .map(|f| f.to_string_value())
            .unwrap_or_else(String::new)
    }
}

impl PrimitiveFieldValue for bool {}
impl FieldValue for bool {
    type ConversionError = ParseBoolError;
    type PrimitiveValue = Self;
    fn from_str(value: &str) -> dioxus::Result<Self, Self::ConversionError> {
        value.parse()
    }
    fn to_primitive_field_value(&self) -> Self::PrimitiveValue {
        *self
    }
}
impl StringValue for bool {
    fn to_string_value(&self) -> String {
        self.to_string()
    }
}