use core::{
fmt::{self, Debug, Formatter},
ops::{Deref, Index},
};
use crate::{
Error,
pointer::JsonPointer,
source::Source,
value::{Array, Number, Object, borrowed, builder::*, owned},
};
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub struct Span<T> {
data: T,
start: usize,
end: usize,
}
#[doc(hidden)]
#[derive(Clone, PartialEq, Eq)]
pub enum GenericValue<S> {
Null,
Array(Array<Span<Self>>),
Object(Object<Span<S>, Span<Self>>),
String(S),
Number(Number),
Boolean(bool),
}
pub type Value<'a> = Span<GenericValue<borrowed::String<'a>>>;
pub type OwnedValue = Span<GenericValue<owned::String>>;
impl<T> Span<T> {
#[inline]
pub(crate) fn new(data: T) -> Self {
Self {
data,
start: 0,
end: 0,
}
}
#[inline]
#[cfg(feature = "serde")]
pub(crate) fn with(data: T, start: usize, end: usize) -> Self {
Self { data, start, end }
}
#[inline]
pub fn data(&self) -> &T {
&self.data
}
#[inline]
pub fn data_mut(&mut self) -> &mut T {
&mut self.data
}
#[inline]
pub fn start(&self) -> usize {
self.start
}
#[inline]
pub fn end(&self) -> usize {
self.end
}
}
impl<S> GenericValue<S> {
#[inline]
pub fn as_null(&self) -> Option<()> {
match self {
Self::Null => Some(()),
_ => None,
}
}
#[inline]
pub fn as_bool(&self) -> Option<bool> {
match self {
Self::Boolean(v) => Some(*v),
_ => None,
}
}
#[inline]
pub fn as_array(&self) -> Option<&Array<Span<Self>>> {
match self {
Self::Array(v) => Some(v),
_ => None,
}
}
#[inline]
pub fn as_object(&self) -> Option<&Object<Span<S>, Span<GenericValue<S>>>> {
match self {
Self::Object(v) => Some(v),
_ => None,
}
}
#[inline]
pub fn as_number(&self) -> Option<Number> {
match *self {
Self::Number(v) => Some(v),
_ => None,
}
}
#[inline]
pub fn as_i64(&self) -> Option<i64> {
self.as_number()?.as_i64()
}
#[inline]
pub fn as_u64(&self) -> Option<u64> {
self.as_number()?.as_u64()
}
#[inline]
pub fn as_f64(&self) -> Option<f64> {
self.as_number()?.as_f64()
}
#[inline]
pub fn is_null(&self) -> bool {
self.as_null().is_some()
}
#[inline]
pub fn is_bool(&self) -> bool {
self.as_bool().is_some()
}
#[inline]
pub fn is_array(&self) -> bool {
self.as_array().is_some()
}
#[inline]
pub fn is_object(&self) -> bool {
self.as_object().is_some()
}
#[inline]
pub fn is_number(&self) -> bool {
self.as_number().is_some()
}
#[inline]
pub fn is_i64(&self) -> bool {
self.as_i64().is_some()
}
#[inline]
pub fn is_u64(&self) -> bool {
self.as_u64().is_some()
}
#[inline]
pub fn is_f64(&self) -> bool {
self.as_f64().is_some()
}
}
impl<S: Deref<Target = str>> GenericValue<S> {
#[inline]
pub fn as_str(&self) -> Option<&str> {
match self {
Self::String(v) => Some(v),
_ => None,
}
}
#[inline]
pub fn is_str(&self) -> bool {
self.as_str().is_some()
}
pub fn pointer<P>(&self, p: P) -> Option<&GenericValue<S>>
where
P: IntoIterator,
P::Item: JsonPointer,
{
let mut tmp = self;
for pointer in p {
tmp = match tmp {
GenericValue::Object(obj) => obj.get(pointer.as_key()?),
GenericValue::Array(arr) => arr.get(pointer.as_index()?),
_ => None,
}?
.data()
}
Some(tmp)
}
pub fn pointer_mut<P>(&mut self, p: P) -> Option<&mut GenericValue<S>>
where
P: IntoIterator,
P::Item: JsonPointer,
{
let mut tmp = self;
for pointer in p {
tmp = match tmp {
GenericValue::Object(obj) => obj.get_mut(pointer.as_key()?),
GenericValue::Array(arr) => arr.get_mut(pointer.as_index()?),
_ => None,
}?
.data_mut()
}
Some(tmp)
}
}
impl<S: Deref<Target = str>> Span<GenericValue<S>> {
pub fn pointer<P>(&self, p: P) -> Option<&Span<GenericValue<S>>>
where
P: IntoIterator,
P::Item: JsonPointer,
{
let mut tmp = self;
for pointer in p {
tmp = match tmp.data() {
GenericValue::Object(obj) => obj.get(pointer.as_key()?),
GenericValue::Array(arr) => arr.get(pointer.as_index()?),
_ => None,
}?
}
Some(tmp)
}
pub fn pointer_mut<P>(&mut self, p: P) -> Option<&mut Span<GenericValue<S>>>
where
P: IntoIterator,
P::Item: JsonPointer,
{
let mut tmp = self;
for pointer in p {
tmp = match tmp.data_mut() {
GenericValue::Object(obj) => obj.get_mut(pointer.as_key()?),
GenericValue::Array(arr) => arr.get_mut(pointer.as_index()?),
_ => None,
}?
}
Some(tmp)
}
}
impl<S> Index<usize> for GenericValue<S> {
type Output = GenericValue<S>;
#[inline]
fn index(&self, idx: usize) -> &Self::Output {
match self.as_array() {
Some(v) => match v.get(idx) {
Some(v) => v.data(),
_ => panic!("given index does not exist in the array"),
},
_ => panic!("value is not an array"),
}
}
}
impl<S: Deref<Target = str>> Index<&str> for GenericValue<S> {
type Output = GenericValue<S>;
#[inline]
fn index(&self, key: &str) -> &Self::Output {
match self.as_object() {
Some(v) => match v.get(key) {
Some(v) => v.data(),
_ => panic!("given key does not exist in the object"),
},
_ => panic!("value is not an object"),
}
}
}
impl<T: Deref<Target = str>> Deref for Span<T> {
type Target = str;
#[inline]
fn deref(&self) -> &Self::Target {
&self.data
}
}
impl<T: Debug> Debug for Span<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "[{}..{}] ", self.start, self.end)?;
self.data.fmt(f)
}
}
impl<'a, S, V> ValueBuilder<'a, S> for Span<GenericValue<V>>
where
S: Source,
V: StringBuilder<'a, S, Span<Error>>,
{
const LAZY: bool = false;
const CUSTOM_LITERAL: bool = false;
type Error = Span<Error>;
type Array = Array<Span<GenericValue<V>>>;
type Object = Object<Span<V>, Span<GenericValue<V>>>;
type String = Span<V>;
#[inline]
fn literal(_: &[u8]) -> Result<Self, Self::Error> {
unimplemented!()
}
#[inline]
fn integer(val: u64, neg: bool) -> Self {
Self::new(GenericValue::Number(match neg {
true => Number::from_i64(val as _),
_ => Number::from_u64(val),
}))
}
#[inline]
fn float(val: f64) -> Self {
unsafe {
Self::new(GenericValue::Number(
Number::from_f64(val).unwrap_unchecked(),
))
}
}
#[inline]
fn bool(val: bool) -> Self {
Self::new(GenericValue::Boolean(val))
}
#[inline]
fn null() -> Self {
Self::new(GenericValue::Null)
}
#[inline]
fn raw(_: &'a [u8]) -> Self {
unimplemented!()
}
#[inline]
fn apply_span(&mut self, start: usize, end: usize) {
self.start = start;
self.end = end;
}
}
impl<'a, S, V> StringBuilder<'a, S, Span<Error>> for Span<V>
where
S: Source,
V: StringBuilder<'a, S, Span<Error>>,
{
const REJECT_CTRL_CHAR: bool = V::REJECT_CTRL_CHAR;
const REJECT_INVALID_ESCAPE: bool = V::REJECT_INVALID_ESCAPE;
#[inline]
fn new() -> Self {
Self::new(V::new())
}
#[inline]
fn on_escape(&mut self, s: &[u8]) {
self.data.on_escape(s)
}
#[inline]
fn on_chunk(&mut self, s: &'a [u8]) {
self.data.on_chunk(s)
}
#[inline]
fn on_final_chunk(&mut self, s: &'a [u8]) {
self.data.on_final_chunk(s)
}
#[inline]
fn apply_span(&mut self, start: usize, end: usize) {
self.start = start;
self.end = end;
}
#[inline]
fn on_complete(&mut self, s: &'a [u8]) -> Result<(), Span<Error>> {
self.data.on_complete(s)
}
}
impl<E: ErrorBuilder> ErrorBuilder for Span<E> {
#[inline]
fn eof() -> Self {
Self::new(E::eof())
}
#[inline]
fn expected_colon() -> Self {
Self::new(E::expected_colon())
}
#[inline]
fn expected_value() -> Self {
Self::new(E::expected_value())
}
#[inline]
fn trailing_comma() -> Self {
Self::new(E::trailing_comma())
}
#[inline]
fn unclosed_string() -> Self {
Self::new(E::unclosed_string())
}
#[inline]
fn invalid_escape() -> Self {
Self::new(E::invalid_escape())
}
#[inline]
fn control_character() -> Self {
Self::new(E::control_character())
}
#[inline]
fn invalid_literal() -> Self {
Self::new(E::invalid_literal())
}
#[inline]
fn trailing_decimal() -> Self {
Self::new(E::trailing_decimal())
}
#[inline]
fn leading_decimal() -> Self {
Self::new(E::leading_decimal())
}
#[inline]
fn leading_zero() -> Self {
Self::new(E::leading_zero())
}
#[inline]
fn number_overflow() -> Self {
Self::new(E::number_overflow())
}
#[inline]
fn unexpected_token() -> Self {
Self::new(E::unexpected_token())
}
#[inline]
fn apply_span(&mut self, start: usize, end: usize) {
self.start = start;
self.end = end;
}
}
impl<'a, S> From<Array<Span<GenericValue<S>>>> for Span<GenericValue<S>> {
#[inline]
fn from(value: Array<Span<GenericValue<S>>>) -> Self {
Self::new(GenericValue::Array(value))
}
}
impl<'a, S> From<Object<Span<S>, Span<GenericValue<S>>>> for Span<GenericValue<S>> {
#[inline]
fn from(value: Object<Span<S>, Span<GenericValue<S>>>) -> Self {
Self::new(GenericValue::Object(value))
}
}
impl<'a, S> From<Span<S>> for Span<GenericValue<S>> {
#[inline]
fn from(value: Span<S>) -> Self {
Span {
data: GenericValue::String(value.data),
start: value.start,
end: value.end,
}
}
}
impl<'a, S: Debug> Debug for GenericValue<S> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
Self::Null => f.write_str("null"),
Self::Array(v) => v.fmt(f),
Self::Boolean(v) => v.fmt(f),
Self::Number(v) => v.fmt(f),
Self::String(v) => v.fmt(f),
Self::Object(v) => v.fmt(f),
}
}
}