clex 0.1.0

Fast C-lang lexer (library)
Documentation
pub trait Float: Sized {
    fn from_str(text: &str) -> Option<Self>;
}

macro_rules! float_impl {
    ($($(#[$meta:meta])* $type:ty;)*) => {
        $(
            $(#[$meta])*
            impl Float for $type {
                fn from_str(text: &str) -> Option<Self> {
                    text.parse().ok()
                }
            }
        )*
    };
}

float_impl! {
    f32;
    f64;
}

fn is_float_suffix(c: char) -> bool {
    matches!(c, 'f' | 'F' | 'l' | 'L')
}

pub fn extract<T: Float>(text: &str) -> Option<T> {
    T::from_str(text.trim_end_matches(is_float_suffix))
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn not_a() {
        assert!(extract::<f32>("a").is_none());
        assert!(extract::<f64>("").is_none());
        assert!(extract::<f32>("-").is_none());
    }

    #[test]
    fn simple() {
        assert_eq!(extract::<f32>("1.25"), Some(1.25));
        assert_eq!(extract::<f64>("1.25"), Some(1.25));
    }

    #[test]
    fn suffixed() {
        assert_eq!(extract::<f32>("1.25f"), Some(1.25));
        assert_eq!(extract::<f64>("1.25L"), Some(1.25));
    }

    #[test]
    fn exponent() {
        assert_eq!(extract::<f32>("1.25e4"), Some(1.25e4));
        assert_eq!(extract::<f32>("1.25E+4"), Some(1.25e4));
        assert_eq!(extract::<f64>("1.25e-4"), Some(1.25e-4));
    }

    #[ignore]
    #[test]
    fn hexadecimal() {
        assert_eq!(extract::<f32>("0x1.4p3"), Some(10.0));
    }
}