use crate::KondutoError;
use serde::Serialize;
use std::fmt::Debug;
use tracing::error;

pub fn to_string<T>(value: T) -> Result<String, KondutoError>
where
    T: Serialize + Debug,
{
    match serde_json::to_value(&value) {
        Ok(value) => match value.as_str() {
            Some(string) => Ok(string.to_owned()),
            None => Err(serialization_error(value)),
        },
        Err(_) => Err(serialization_error(value)),
    }
}

#[expect(
    clippy::expect_used,
    reason = "In this context this function is infallible"
)]
pub fn to_string_infallible<T>(value: T) -> String
where
    T: Serialize + Debug,
{
    to_string(value).expect("Converting Source to string should not fail")
}

fn serialization_error<T>(value: T) -> KondutoError
where
    T: Debug,
{
    let msg = format!(
        "[konduto-sdk] - unexpected error serializing value: {:?}.",
        value
    );
    error!("{}", msg);
    KondutoError::ValidationError(msg)
}
