pub mod bytes;
pub(crate) mod equivalent;
pub mod error;
pub mod format;
#[doc(hidden)]
pub mod key;
#[doc(hidden)]
pub mod keys;
pub mod list;
pub mod map;
#[doc(hidden)]
pub mod meta;
pub(crate) mod number;
#[doc(hidden)]
pub mod operation;
pub mod parse;
pub(crate) mod print;
pub mod span;
#[doc(hidden)]
pub mod tracer;
use crate::value::number::Number;
use crate::value::print::Print;
use crate::value::span::Span;
use bytes::Bytes;
use key::Key;
use keys::Keys;
use list::List;
use map::Map;
use meta::Meta;
use serde::Deserialize;
use serde::Serialize;
use tracer::Tracer;
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum Value {
Bytes(Bytes),
List(List),
Map(Map),
}
impl core::fmt::Display for Value {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str(&String::from_utf8_lossy(&self.clone().print_syntax()))
}
}
impl Default for Value {
fn default() -> Self {
Value::Bytes(Bytes::default())
}
}
impl From<Vec<u8>> for Value {
fn from(value: Vec<u8>) -> Self {
Value::Bytes(Bytes::from(value))
}
}
impl From<&[u8]> for Value {
fn from(value: &[u8]) -> Self {
Value::from(value.to_vec())
}
}
impl From<String> for Value {
fn from(value: String) -> Self {
Value::from(value.into_bytes())
}
}
impl From<&str> for Value {
fn from(value: &str) -> Self {
Value::from(value.to_string())
}
}
impl From<char> for Value {
fn from(value: char) -> Self {
Value::from(value.to_string())
}
}
impl From<usize> for Value {
fn from(value: usize) -> Self {
Value::from(value.to_string())
}
}
impl From<isize> for Value {
fn from(value: isize) -> Self {
Value::from(value.to_string())
}
}
impl From<bool> for Value {
fn from(value: bool) -> Self {
match value {
true => Value::from(value.to_string()),
false => Value::default(),
}
}
}
impl From<Span> for Value {
fn from(value: Span) -> Self {
Value::List(List::default().with(value.0).with(value.1))
}
}
impl From<Key> for Value {
fn from(value: Key) -> Self {
Value::from(Vec::<u8>::from(value))
}
}
impl From<Keys> for Value {
fn from(value: Keys) -> Self {
Value::List(value.into_vec().into_iter().map(Value::from).collect())
}
}
impl From<Tracer> for Value {
fn from(value: Tracer) -> Self {
Value::Map(
Map::default()
.with("source", value.source)
.with("span", value.span)
.with("keys", value.keys)
.with("raw", value.raw),
)
}
}
impl From<Bytes> for Value {
fn from(value: Bytes) -> Self {
Value::Bytes(value)
}
}
impl From<List> for Value {
fn from(value: List) -> Self {
Value::List(value)
}
}
impl From<Map> for Value {
fn from(value: Map) -> Self {
Value::Map(value)
}
}
impl<T: Into<Value>> From<Option<T>> for Value {
fn from(value: Option<T>) -> Self {
value.map(Into::into).unwrap_or_default()
}
}
impl TryFrom<Value> for Bytes {
type Error = ();
fn try_from(value: Value) -> Result<Self, Self::Error> {
match value {
Value::Bytes(v) => Ok(v),
_ => Err(()),
}
}
}
impl From<Value> for List {
fn from(value: Value) -> Self {
vec![value].into()
}
}
impl TryFrom<Value> for Map {
type Error = ();
fn try_from(value: Value) -> Result<Self, Self::Error> {
match value {
Value::Map(v) => Ok(v),
_ => Err(()),
}
}
}
impl Value {
#[doc(hidden)]
pub fn with_data(mut self, other: Value) -> Self {
other
.append_meta(self.take_meta())
.with_tracer(self.take_tracer())
}
#[doc(hidden)]
pub fn with_meta<K: Into<Vec<u8>>, V: Into<Vec<u8>>>(mut self, key: K, value: V) -> Self {
match &mut self {
Value::Bytes(v) => v.meta.push(key, value),
Value::List(v) => v.meta.push(key, value),
Value::Map(v) => v.meta.push(key, value),
}
self
}
#[doc(hidden)]
pub fn without_meta(mut self, key: &[u8]) -> Self {
match &mut self {
Value::Bytes(v) => v.meta.remove(key),
Value::List(v) => v.meta.remove(key),
Value::Map(v) => v.meta.remove(key),
};
self
}
#[doc(hidden)]
pub fn append_meta(mut self, meta: Meta) -> Self {
match &mut self {
Value::Bytes(v) => v.meta.append(meta),
Value::List(v) => v.meta.append(meta),
Value::Map(v) => v.meta.append(meta),
}
self
}
#[doc(hidden)]
pub fn with_safe(self) -> Self {
self.with_meta("internal-safe", "")
}
#[doc(hidden)]
pub fn safe(&self) -> bool {
self.meta().contains(b"internal-safe")
}
#[doc(hidden)]
pub fn meta(&self) -> &Meta {
match self {
Value::Bytes(v) => &v.meta,
Value::List(v) => &v.meta,
Value::Map(v) => &v.meta,
}
}
#[doc(hidden)]
pub fn take_meta(&mut self) -> Meta {
core::mem::take(match self {
Value::Bytes(v) => &mut v.meta,
Value::List(v) => &mut v.meta,
Value::Map(v) => &mut v.meta,
})
}
#[doc(hidden)]
pub fn meta_mut(&mut self) -> &mut Meta {
match self {
Value::Bytes(v) => &mut v.meta,
Value::List(v) => &mut v.meta,
Value::Map(v) => &mut v.meta,
}
}
#[doc(hidden)]
pub fn with_tracer<T: Into<Tracer>>(mut self, tracer: T) -> Self {
self.trace(tracer);
self
}
#[doc(hidden)]
pub fn take_tracer(&mut self) -> Tracer {
core::mem::take(match self {
Value::Bytes(v) => &mut v.tracer,
Value::List(v) => &mut v.tracer,
Value::Map(v) => &mut v.tracer,
})
}
#[doc(hidden)]
pub fn trace<T: Into<Tracer>>(&mut self, tracer: T) {
match self {
Value::Bytes(v) => v.trace(tracer),
Value::List(v) => v.trace(tracer),
Value::Map(v) => v.trace(tracer),
}
}
#[doc(hidden)]
pub fn tracer(&self) -> &Tracer {
match self {
Value::Bytes(v) => v.tracer(),
Value::List(v) => v.tracer(),
Value::Map(v) => v.tracer(),
}
}
#[doc(hidden)]
pub(crate) fn len(&self) -> usize {
match self {
Value::Bytes(v) => v.data.len(),
Value::List(v) => v.data.len(),
Value::Map(v) => v.data.len(),
}
}
#[doc(hidden)]
pub fn is_empty(&self) -> bool {
match self {
Value::Bytes(v) => v.is_empty(),
Value::List(v) => v.is_empty(),
Value::Map(v) => v.is_empty(),
}
}
#[doc(hidden)]
pub fn as_str(&self) -> Option<&str> {
self.as_bytes().map(parse::str).transpose().ok().flatten()
}
pub fn as_usize(&self) -> Option<usize> {
self.as_bytes()
.and_then(|b| Number::try_from(b).ok())
.and_then(|n| n.try_into().ok())
}
#[doc(hidden)]
pub fn as_isize(&self) -> Option<isize> {
self.as_bytes()
.and_then(|b| Number::try_from(b).ok())
.and_then(|n| n.try_into().ok())
}
#[doc(hidden)]
pub(crate) fn as_number(&self) -> Option<Number> {
match self {
Value::Bytes(v) => Number::try_from(v.as_bytes()).ok(),
_ => None,
}
}
#[doc(hidden)]
pub fn as_bytes(&self) -> Option<&[u8]> {
match self {
Value::Bytes(v) => Some(v.as_bytes()),
Value::List(_) => None,
Value::Map(_) => None,
}
}
#[doc(hidden)]
pub fn as_list(&self) -> Option<&List> {
match self {
Value::Bytes(_) => None,
Value::List(v) => Some(v),
Value::Map(_) => None,
}
}
#[doc(hidden)]
pub fn as_map(&self) -> Option<&Map> {
match self {
Value::Bytes(_) => None,
Value::List(_) => None,
Value::Map(v) => Some(v),
}
}
#[doc(hidden)]
pub fn into_bytes(mut self) -> Bytes {
Bytes {
tracer: self.take_tracer(),
meta: self.take_meta(),
data: self.join(),
}
}
#[doc(hidden)]
pub fn into_list(self) -> List {
match self {
Value::Bytes(_) if !self.is_empty() => List::from(self),
Value::Bytes(_) => List::default(),
Value::List(v) => v,
Value::Map(v) => v.data.into_values().collect::<List>(),
}
}
#[doc(hidden)]
pub fn into_map(self) -> Map {
match self {
Value::Bytes(v) => Map::from((b"", v)),
Value::List(v) => v
.into_iter()
.enumerate()
.map(|(i, v)| (i.to_string().into_bytes(), v))
.collect(),
Value::Map(v) => v,
}
}
#[doc(hidden)]
pub fn into_other(self, other: &Value) -> Value {
match other {
Value::Bytes(_) => self.into_bytes().into(),
Value::List(_) => self.into_list().into(),
Value::Map(_) => self.into_map().into(),
}
}
#[doc(hidden)]
pub fn into_parts(self) -> List {
match self {
Value::Bytes(v) => v.as_chars(),
_ => self.into_list(),
}
}
#[doc(hidden)]
pub(crate) fn into_lists(values: Vec<Value>) -> Vec<List> {
values.into_iter().map(Value::into_list).collect()
}
#[doc(hidden)]
pub fn into_string(self) -> Option<String> {
String::from_utf8(self.join()).ok()
}
#[doc(hidden)]
pub fn into_string_lossy(self) -> String {
String::from_utf8(self.join())
.unwrap_or_else(|e| String::from_utf8_lossy(e.as_bytes()).into())
}
#[doc(hidden)]
pub(crate) fn intersection(values: Vec<Value>) -> Value {
List::intersection(Value::into_lists(values)).into()
}
#[doc(hidden)]
pub(crate) fn union(values: Vec<Value>) -> Value {
List::union(Value::into_lists(values)).into()
}
#[doc(hidden)]
pub fn flatten(self) -> Self {
Value::Bytes(self.into_bytes())
}
#[doc(hidden)]
pub fn clear(self) -> Value {
match self {
Value::Bytes(v) => Value::from(v.clear()),
Value::List(v) => Value::from(v.clear()),
Value::Map(v) => Value::from(v.clear()),
}
}
#[doc(hidden)]
pub fn split(self) -> Vec<Value> {
match self {
Value::Bytes(_) => self
.into_string_lossy()
.split_whitespace()
.filter(|c| !c.is_empty())
.map(Value::from)
.collect(),
Value::List(v) => v.data,
Value::Map(v) => v.data.into_values().collect(),
}
}
#[doc(hidden)]
pub fn join(self) -> Vec<u8> {
match self {
Value::Bytes(v) => v.join(),
Value::List(v) => v.join(),
Value::Map(v) => v.join(),
}
}
#[doc(hidden)]
pub(crate) fn into_first(self) -> Value {
match self {
Value::Bytes(v) => v.first().into(),
Value::List(v) => v.data.first().cloned().unwrap_or_else(Value::default),
Value::Map(v) => v
.data
.first()
.map(|(_, v)| v.clone())
.unwrap_or_else(Value::default),
}
}
#[doc(hidden)]
pub(crate) fn into_last(self) -> Value {
match self {
Value::Bytes(v) => v.last().into(),
Value::List(v) => v.data.last().cloned().unwrap_or_else(Value::default),
Value::Map(v) => v
.data
.last()
.map(|(_, v)| v.clone())
.unwrap_or_else(Value::default),
}
}
#[doc(hidden)]
pub(crate) fn into_rest(self) -> Value {
if self.is_empty() {
return self;
}
match self {
Value::Bytes(v) => v.rest().into(),
Value::List(mut v) => {
v.data.remove(0);
v.into()
}
Value::Map(mut v) => {
v.data.shift_remove_index(0);
v.into()
}
}
}
#[doc(hidden)]
pub fn fold(&mut self, other: Self) {
match (self, other) {
(Value::Bytes(a), Value::Bytes(b)) => a.fold(b),
(Value::List(a), Value::List(b)) => a.fold(b),
(Value::Map(a), Value::Map(b)) => a.fold(b),
(a, b) => *a = b,
}
}
}
#[cfg(test)]
mod test {
use crate::value::Value;
use crate::value::list::List;
use crate::value::map::Map;
#[test]
fn test_join() {
let bytes = Value::from("a");
let map = Value::Map(Map::default().with("b", "c"));
let value = Value::List(List::default().with(bytes).with(map));
assert_eq!(value.join(), b"ac")
}
#[test]
fn test_display() {
let bytes = Value::from("a");
let map = Value::Map(Map::default().with("b", "c"));
let value = Value::List(List::default().with(bytes).with(map));
assert_eq!(value.to_string(), r#"["a" {b "c"}]"#)
}
}