aura-gui 0.3.5

UI nativa acelerada por GPU para escritorio, Android e iOS, en un solo crate: estilo tipo Tailwind, componentes, sombras, animaciones y agentes de IA. Reposo a cero. Licencia AGPL-3.0 o comercial.
//! Conversión a JSON de los tipos que `ui.persisted("clave", valor)` guarda en el [`Store`] de la app.

use serde_json::Value;

/// Rasgo de los valores que `ui.persisted("clave", valor)` puede leer y escribir en el JSON de ajustes de la app.
pub trait PersistValue: Sized + 'static {
    fn to_json(&self) -> Value;
    fn from_json(value: &Value) -> Option<Self>;
}

impl PersistValue for bool {
    fn to_json(&self) -> Value {
        Value::Bool(*self)
    }

    fn from_json(value: &Value) -> Option<Self> {
        value.as_bool()
    }
}

impl PersistValue for String {
    fn to_json(&self) -> Value {
        Value::String(self.clone())
    }

    fn from_json(value: &Value) -> Option<Self> {
        value.as_str().map(str::to_owned)
    }
}

macro_rules! persist_int {
    ($($ty:ty),* $(,)?) => {
        $(
            impl PersistValue for $ty {
                fn to_json(&self) -> Value {
                    Value::from(*self)
                }

                fn from_json(value: &Value) -> Option<Self> {
                    value.as_i64().and_then(|n| Self::try_from(n).ok())
                        .or_else(|| value.as_u64().and_then(|n| Self::try_from(n).ok()))
                }
            }
        )*
    };
}

persist_int!(i8, i16, i32, i64, isize, u8, u16, u32, u64, usize);

impl PersistValue for f32 {
    fn to_json(&self) -> Value {
        Value::from(*self)
    }

    fn from_json(value: &Value) -> Option<Self> {
        value.as_f64().map(|n| n as f32)
    }
}

impl PersistValue for f64 {
    fn to_json(&self) -> Value {
        Value::from(*self)
    }

    fn from_json(value: &Value) -> Option<Self> {
        value.as_f64()
    }
}

impl<T: PersistValue> PersistValue for Vec<T> {
    fn to_json(&self) -> Value {
        Value::Array(self.iter().map(PersistValue::to_json).collect())
    }

    fn from_json(value: &Value) -> Option<Self> {
        value.as_array()?.iter().map(T::from_json).collect()
    }
}