use super::*;
use bytes::BufMut;
use std::{
fmt,
hash::{Hash, Hasher},
str::FromStr,
};
#[derive(Clone)]
pub struct Value {
pub(crate) buffer: Box<[u8]>,
}
impl Value {
pub fn null() -> Self {
Self::from(())
}
pub fn array<'a>(iter: impl IntoIterator<Item = ValueRef<'a>>) -> Self {
Self::from_builder(0, |b| {
b.begin_array();
for v in iter {
b.add_value(v);
}
b.end_array();
})
}
pub fn object<'a>(iter: impl IntoIterator<Item = (&'a str, ValueRef<'a>)>) -> Self {
Self::from_builder(0, |b| {
b.begin_object();
for (k, v) in iter {
b.add_string(k);
b.add_value(v);
}
b.end_object();
})
}
pub fn from_text(json: &[u8]) -> serde_json::Result<Self> {
use ::serde::de::DeserializeSeed;
let mut builder = Builder::with_capacity(json.len());
let mut deserializer = serde_json::Deserializer::from_slice(json);
builder.deserialize(&mut deserializer)?;
deserializer.end()?;
Ok(builder.finish())
}
#[cfg(feature = "simd-json")]
pub fn from_text_mut(json: &mut [u8]) -> simd_json::Result<Self> {
use ::serde::de::DeserializeSeed;
let mut builder = Builder::with_capacity(json.len());
let mut deserializer = simd_json::Deserializer::from_slice(json)?;
builder.deserialize(&mut deserializer)?;
Ok(builder.finish())
}
pub fn from_bytes(bytes: &[u8]) -> Self {
Self {
buffer: bytes.into(),
}
}
pub fn as_ref(&self) -> ValueRef<'_> {
ValueRef::from_bytes(&self.buffer)
}
pub fn as_bytes(&self) -> &[u8] {
&self.buffer
}
pub fn as_null(&self) -> Option<()> {
self.as_ref().as_null()
}
pub fn as_bool(&self) -> Option<bool> {
self.as_ref().as_bool()
}
pub fn as_i64(&self) -> Option<i64> {
self.as_ref().as_i64()
}
pub fn as_u64(&self) -> Option<u64> {
self.as_ref().as_u64()
}
pub fn as_f64(&self) -> Option<f64> {
self.as_ref().as_f64()
}
pub fn as_str(&self) -> Option<&str> {
self.as_ref().as_str()
}
pub fn as_array(&self) -> Option<ArrayRef<'_>> {
self.as_ref().as_array()
}
pub fn as_object(&self) -> Option<ObjectRef<'_>> {
self.as_ref().as_object()
}
pub fn is_null(&self) -> bool {
self.as_ref().is_null()
}
pub fn is_boolean(&self) -> bool {
self.as_ref().is_boolean()
}
pub fn is_number(&self) -> bool {
self.as_ref().is_number()
}
pub fn is_u64(&self) -> bool {
self.as_ref().is_u64()
}
pub fn is_i64(&self) -> bool {
self.as_ref().is_i64()
}
pub fn is_f64(&self) -> bool {
self.as_ref().is_f64()
}
pub fn is_string(&self) -> bool {
self.as_ref().is_string()
}
pub fn is_array(&self) -> bool {
self.as_ref().is_array()
}
pub fn is_object(&self) -> bool {
self.as_ref().is_object()
}
pub fn capacity(&self) -> usize {
self.buffer.len()
}
pub fn get(&self, index: impl Index) -> Option<ValueRef<'_>> {
index.index_into(self.as_ref())
}
pub fn pointer<'a>(&'a self, pointer: &str) -> Option<ValueRef<'a>> {
self.as_ref().pointer(pointer)
}
pub fn array_push(&mut self, value: ValueRef<'_>) {
let len = self.as_array().expect("not array").len();
let offset = self.buffer.len() - 4 - 4 - 4 - 4 * len;
let mut buffer = std::mem::take(&mut self.buffer).into_vec();
buffer.reserve_exact(value.capacity() + 4);
buffer.truncate(buffer.len() - 12);
buffer.splice(offset..offset, value.as_slice().iter().copied());
buffer.put_slice(value.make_entry(offset).as_bytes());
buffer.put_u32_ne((len + 1) as u32);
buffer.put_u32_ne((buffer.len() + 4) as u32);
buffer.put_slice(Entry::array(buffer.len()).as_bytes());
self.buffer = buffer.into();
}
fn from_builder(capacity: usize, f: impl FnOnce(&mut Builder)) -> Self {
let mut builder = Builder::with_capacity(capacity);
f(&mut builder);
builder.finish()
}
}
impl fmt::Debug for Value {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.as_ref().fmt(f)
}
}
impl fmt::Display for Value {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.as_ref().fmt(f)
}
}
impl PartialEq for Value {
fn eq(&self, other: &Self) -> bool {
self.as_ref().eq(&other.as_ref())
}
}
impl Eq for Value {}
impl PartialOrd for Value {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Value {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.as_ref().cmp(&other.as_ref())
}
}
impl Hash for Value {
fn hash<H: Hasher>(&self, state: &mut H) {
self.as_ref().hash(state)
}
}
impl Default for Value {
fn default() -> Self {
Self::null()
}
}
impl From<serde_json::Value> for Value {
fn from(value: serde_json::Value) -> Self {
Self::from(&value)
}
}
impl From<&serde_json::Value> for Value {
fn from(value: &serde_json::Value) -> Self {
Self::from_builder(0, |b| b.add_serde_value(value))
}
}
impl From<serde_json::Number> for Value {
fn from(value: serde_json::Number) -> Self {
Self::from(&value)
}
}
impl From<&serde_json::Number> for Value {
fn from(n: &serde_json::Number) -> Self {
Self::from_builder(0, |b| b.add_serde_number(n))
}
}
impl From<Value> for serde_json::Value {
fn from(value: Value) -> Self {
value.as_ref().into()
}
}
impl<W: AsMut<Vec<u8>>> Builder<W> {
fn add_serde_value(&mut self, value: &serde_json::Value) {
match value {
serde_json::Value::Null => self.add_null(),
serde_json::Value::Bool(b) => self.add_bool(*b),
serde_json::Value::Number(n) => self.add_serde_number(n),
serde_json::Value::String(s) => self.add_string(s),
serde_json::Value::Array(a) => {
self.begin_array();
for v in a.iter() {
self.add_serde_value(v);
}
self.end_array();
}
serde_json::Value::Object(o) => {
self.begin_object();
for (k, v) in o.iter() {
self.add_string(k);
self.add_serde_value(v);
}
self.end_object()
}
}
}
fn add_serde_number(&mut self, n: &serde_json::Number) {
if let Some(i) = n.as_u64() {
self.add_u64(i)
} else if let Some(i) = n.as_i64() {
self.add_i64(i)
} else if let Some(f) = n.as_f64() {
self.add_f64(f)
} else {
panic!("invalid number");
}
}
}
impl FromStr for Value {
type Err = serde_json::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Self::from_text(s.as_bytes())
}
}
impl From<()> for Value {
fn from(_: ()) -> Self {
Self::from_builder(4, |b| b.add_null())
}
}
impl From<bool> for Value {
fn from(v: bool) -> Self {
Self::from_builder(4, |b| b.add_bool(v))
}
}
impl From<u8> for Value {
fn from(v: u8) -> Self {
Self::from(v as u64)
}
}
impl From<u16> for Value {
fn from(v: u16) -> Self {
Self::from(v as u64)
}
}
impl From<u32> for Value {
fn from(v: u32) -> Self {
Self::from(v as u64)
}
}
impl From<u64> for Value {
fn from(v: u64) -> Self {
Self::from_builder(1 + 8 + 4, |b| b.add_u64(v))
}
}
impl From<usize> for Value {
fn from(v: usize) -> Self {
Self::from(v as u64)
}
}
impl From<i8> for Value {
fn from(v: i8) -> Self {
Self::from(v as i64)
}
}
impl From<i16> for Value {
fn from(v: i16) -> Self {
Self::from(v as i64)
}
}
impl From<i32> for Value {
fn from(v: i32) -> Self {
Self::from(v as i64)
}
}
impl From<i64> for Value {
fn from(v: i64) -> Self {
Self::from_builder(1 + 8 + 4, |b| b.add_i64(v))
}
}
impl From<isize> for Value {
fn from(v: isize) -> Self {
Self::from(v as u64)
}
}
impl From<f32> for Value {
fn from(v: f32) -> Self {
Self::from(v as f64)
}
}
impl From<f64> for Value {
fn from(v: f64) -> Self {
Self::from_builder(1 + 8 + 4, |b| b.add_f64(v))
}
}
impl From<&str> for Value {
fn from(s: &str) -> Self {
Self::from_builder(s.len() + 8, |b| b.add_string(s))
}
}
impl From<&[u8]> for Value {
fn from(s: &[u8]) -> Self {
Self::from_bytes(s)
}
}
impl From<ValueRef<'_>> for Value {
fn from(v: ValueRef<'_>) -> Self {
Self::from_builder(v.capacity() + 4, |b| b.add_value(v))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn from_serde() {
let serde_value: serde_json::Value = r#"
{
"name": "John Doe",
"age": 43,
"phones": [
"+44 1234567",
"+44 2345678"
]
}"#
.parse()
.unwrap();
let _value = Value::from(&serde_value);
}
#[test]
#[should_panic]
fn from_nan() {
_ = Value::from(f64::NAN);
}
#[test]
#[should_panic]
fn from_inf() {
_ = Value::from(f64::INFINITY);
}
#[test]
#[should_panic]
fn from_neg_inf() {
_ = Value::from(f64::NEG_INFINITY);
}
#[test]
fn value_size() {
assert_eq!(Value::from(0).capacity(), 1 + 4);
assert_eq!(Value::from(1).capacity(), 1 + 1 + 4);
assert_eq!(Value::from(128).capacity(), 1 + 2 + 4);
assert_eq!(Value::from(32768).capacity(), 1 + 4 + 4);
assert_eq!(Value::from(2_147_483_648_u64).capacity(), 1 + 8 + 4);
assert_eq!(Value::from(i8::MIN).capacity(), 1 + 1 + 4);
assert_eq!(Value::from(i16::MIN).capacity(), 1 + 2 + 4);
assert_eq!(Value::from(i32::MIN).capacity(), 1 + 4 + 4);
assert_eq!(Value::from(i64::MIN).capacity(), 1 + 8 + 4);
assert_eq!(Value::from(0.0f32).capacity(), 1 + 8 + 4);
assert_eq!(Value::from(0.0f64).capacity(), 1 + 8 + 4);
}
}