use ron::extensions::Extensions;
use ron::ser::PrettyConfig;
use serde::{Serialize, de::DeserializeOwned};

#[derive(Debug, thiserror::Error)]
pub enum RonError {
    #[error("serialize: {0}")]
    Serialize(#[from] ron::Error),
    #[error("deserialize: {0}")]
    Deserialize(#[from] ron::error::SpannedError),
}

#[must_use]
pub fn pretty_config() -> PrettyConfig {
    PrettyConfig::new()
        .struct_names(true)
        .separate_tuple_members(false)
        .compact_arrays(true)
        .depth_limit(usize::MAX)
        .indentor("    ".to_owned())
        .extensions(
            Extensions::UNWRAP_NEWTYPES
                | Extensions::IMPLICIT_SOME
                | Extensions::EXPLICIT_STRUCT_NAMES,
        )
}

pub fn to_string<T: Serialize>(value: &T) -> Result<String, RonError> {
    Ok(ron::ser::to_string_pretty(value, pretty_config())?)
}

pub fn from_str<T: DeserializeOwned>(input: &str) -> Result<T, RonError> {
    Ok(ron::de::from_str(input)?)
}
