//! JSON pointer/accessor helpers over serde_json values.

use crate::{Error, Result};
use serde_json::Value;

pub(crate) fn string_pointer(payload: &Value, pointer: &str) -> Option<String> {
    payload
        .pointer(pointer)
        .and_then(Value::as_str)
        .map(str::trim)
        .filter(|value| !value.is_empty())
        .map(str::to_string)
}

pub(crate) fn required_string<'a>(payload: &'a Value, key: &str) -> Result<&'a str> {
    payload
        .get(key)
        .and_then(Value::as_str)
        .filter(|value| !value.is_empty())
        .ok_or_else(|| Error::Validation(format!("payload.{key} must be a non-empty string")))
}

pub(crate) fn i64_pointer(payload: &Value, pointer: &str) -> Option<i64> {
    let value = payload.pointer(pointer)?;
    value
        .as_i64()
        .or_else(|| value.as_u64().and_then(|value| i64::try_from(value).ok()))
        .or_else(|| {
            value
                .as_str()
                .and_then(|value| value.trim().parse::<i64>().ok())
        })
}
