use serde::de::DeserializeOwned;
use serde_json::Value;
use crate::{JsonDecodeError, JsonDecodeOptions, JsonTopLevelKind, LenientJsonNormalizer};
#[derive(Debug, Clone, Default)]
pub struct LenientJsonDecoder {
normalizer: LenientJsonNormalizer,
}
impl LenientJsonDecoder {
#[must_use]
pub const fn new(options: JsonDecodeOptions) -> Self {
Self {
normalizer: LenientJsonNormalizer::new(options),
}
}
#[must_use]
pub const fn options(&self) -> &JsonDecodeOptions {
self.normalizer.options()
}
pub fn decode<T>(&self, input: &str) -> Result<T, JsonDecodeError>
where
T: DeserializeOwned,
{
let value = self.decode_value(input)?;
serde_json::from_value(value).map_err(JsonDecodeError::deserialize)
}
pub fn decode_object<T>(&self, input: &str) -> Result<T, JsonDecodeError>
where
T: DeserializeOwned,
{
let value = self.decode_value(input)?;
self.ensure_top_level(&value, JsonTopLevelKind::Object)?;
serde_json::from_value(value).map_err(JsonDecodeError::deserialize)
}
pub fn decode_array<T>(&self, input: &str) -> Result<Vec<T>, JsonDecodeError>
where
T: DeserializeOwned,
{
let value = self.decode_value(input)?;
self.ensure_top_level(&value, JsonTopLevelKind::Array)?;
serde_json::from_value(value).map_err(JsonDecodeError::deserialize)
}
pub fn decode_value(&self, input: &str) -> Result<Value, JsonDecodeError> {
let normalized = self.normalizer.normalize(input)?;
serde_json::from_str(normalized.as_ref()).map_err(JsonDecodeError::invalid_json)
}
fn ensure_top_level(
&self,
value: &Value,
expected: JsonTopLevelKind,
) -> Result<(), JsonDecodeError> {
let actual = JsonTopLevelKind::of(value);
if actual == expected {
Ok(())
} else {
Err(JsonDecodeError::unexpected_top_level(expected, actual))
}
}
}