use std::{
convert::Infallible,
fmt::{Debug, Display},
};
#[derive(Clone, Copy)]
pub enum ValuePointerRef<'a> {
Origin,
Key {
key: &'a str,
prev: &'a ValuePointerRef<'a>,
},
Index {
index: usize,
prev: &'a ValuePointerRef<'a>,
},
}
impl Default for ValuePointerRef<'_> {
fn default() -> Self {
Self::Origin
}
}
impl<'a> ValuePointerRef<'a> {
#[must_use]
pub fn push_key(&'a self, key: &'a str) -> Self {
Self::Key { key, prev: self }
}
#[must_use]
pub fn push_index(&'a self, index: usize) -> Self {
Self::Index { index, prev: self }
}
pub fn is_origin(&self) -> bool {
matches!(self, ValuePointerRef::Origin)
}
pub fn last_field(&self) -> Option<&str> {
match self {
ValuePointerRef::Origin => None,
ValuePointerRef::Key { key, .. } => Some(key),
ValuePointerRef::Index { prev, .. } => prev.last_field(),
}
}
pub fn first_field(&self) -> Option<&str> {
match self {
ValuePointerRef::Origin => None,
ValuePointerRef::Key { key, prev } => prev.first_field().or(Some(key)),
ValuePointerRef::Index { prev, .. } => prev.first_field(),
}
}
pub fn to_owned(&self) -> ValuePointer {
let mut cur = self;
let mut components = vec![];
loop {
match cur {
ValuePointerRef::Origin => break,
ValuePointerRef::Key { key, prev } => {
components.push(ValuePointerComponent::Key(key.to_string()));
cur = prev;
}
ValuePointerRef::Index { index, prev } => {
components.push(ValuePointerComponent::Index(*index));
cur = prev;
}
}
}
let components = components.into_iter().rev().collect();
ValuePointer { path: components }
}
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum ValuePointerComponent {
Key(String),
Index(usize),
}
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
pub struct ValuePointer {
pub path: Vec<ValuePointerComponent>,
}
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum ValueKind {
Null,
Boolean,
Integer,
NegativeInteger,
Float,
String,
Sequence,
Map,
}
impl Display for ValueKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ValueKind::Null => write!(f, "Null"),
ValueKind::Boolean => write!(f, "Boolean"),
ValueKind::Integer => write!(f, "Integer"),
ValueKind::NegativeInteger => write!(f, "NegativeInteger"),
ValueKind::Float => write!(f, "Float"),
ValueKind::String => write!(f, "String"),
ValueKind::Sequence => write!(f, "Sequence"),
ValueKind::Map => write!(f, "Map"),
}
}
}
impl Debug for ValueKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Display::fmt(self, f)
}
}
#[derive(Debug)]
pub enum Value<V: IntoValue> {
Null,
Boolean(bool),
Integer(u64),
NegativeInteger(i64),
Float(f64),
String(String),
Sequence(V::Sequence),
Map(V::Map),
}
impl<V: IntoValue> Value<V> {
pub fn kind(&self) -> ValueKind {
match self {
Value::Null => ValueKind::Null,
Value::Boolean(_) => ValueKind::Boolean,
Value::Integer(_) => ValueKind::Integer,
Value::NegativeInteger(_) => ValueKind::NegativeInteger,
Value::Float(_) => ValueKind::Float,
Value::String(_) => ValueKind::String,
Value::Sequence(_) => ValueKind::Sequence,
Value::Map(_) => ValueKind::Map,
}
}
}
pub trait IntoValue: Sized {
type Sequence: Sequence<Value = Self>;
type Map: Map<Value = Self>;
fn kind(&self) -> ValueKind;
fn into_value(self) -> Value<Self>;
}
pub trait Sequence {
type Value: IntoValue;
type Iter: Iterator<Item = Self::Value>;
fn len(&self) -> usize;
fn into_iter(self) -> Self::Iter;
fn is_empty(&self) -> bool {
self.len() == 0
}
}
pub trait Map {
type Value: IntoValue;
type Iter: Iterator<Item = (String, Self::Value)>;
fn len(&self) -> usize;
fn remove(&mut self, key: &str) -> Option<Self::Value>;
fn into_iter(self) -> Self::Iter;
fn is_empty(&self) -> bool {
self.len() == 0
}
}
impl IntoValue for Infallible {
type Sequence = Self;
type Map = Self;
fn kind(&self) -> ValueKind {
unreachable!()
}
fn into_value(self) -> Value<Self> {
unreachable!()
}
}
impl Sequence for Infallible {
type Value = Self;
type Iter = std::iter::Empty<Infallible>;
fn len(&self) -> usize {
unreachable!()
}
fn into_iter(self) -> Self::Iter {
unreachable!()
}
}
impl Map for Infallible {
type Value = Self;
type Iter = std::iter::Empty<(String, Infallible)>;
fn len(&self) -> usize {
unreachable!()
}
fn remove(&mut self, _key: &str) -> Option<Self::Value> {
unreachable!()
}
fn into_iter(self) -> Self::Iter {
unreachable!()
}
}