// src/lib.rs

#![doc = include_str!("../README.md")]

pub mod prelude;

#[macro_use]
pub mod core;

pub mod debug;

#[derive(Debug, Clone, Copy, PartialEq)]
pub enum AxiValue {
    Str(&'static str),
    Num(&'static str),
    Bool(bool),
    Null,
}

impl AxiValue {
    pub fn is_null(&self) -> bool {
        matches!(self, AxiValue::Null)
    }

    pub fn as_i64(&self) -> Option<i64> {
        if let AxiValue::Num(s) = self {
            s.parse().ok()
        } else {
            None
        }
    }

    pub fn as_f64(&self) -> Option<f64> {
        if let AxiValue::Num(s) = self {
            s.parse().ok()
        } else {
            None
        }
    }
}

pub trait LiteralToAxi {
    fn into_axi(self, stringified: &'static str) -> AxiValue;
}

impl LiteralToAxi for &'static str {
    #[inline(always)]
    fn into_axi(self, _: &'static str) -> AxiValue {
        AxiValue::Str(self)
    }
}
impl LiteralToAxi for bool {
    #[inline(always)]
    fn into_axi(self, _: &'static str) -> AxiValue {
        AxiValue::Bool(self)
    }
}
impl LiteralToAxi for i32 {
    #[inline(always)]
    fn into_axi(self, s: &'static str) -> AxiValue {
        AxiValue::Num(s)
    }
}
impl LiteralToAxi for f64 {
    #[inline(always)]
    fn into_axi(self, s: &'static str) -> AxiValue {
        AxiValue::Num(s)
    }
}
impl LiteralToAxi for i64 {
    #[inline(always)]
    fn into_axi(self, s: &'static str) -> AxiValue {
        AxiValue::Num(s)
    }
}

#[doc(hidden)]
#[inline(always)]
pub fn into_axi_value<T: LiteralToAxi>(val: T, stringified: &'static str) -> AxiValue {
    val.into_axi(stringified)
}
