use std::{
fmt::Debug,
iter::FusedIterator,
ops::{Deref, DerefMut, RangeBounds},
slice::{from_raw_parts, from_raw_parts_mut},
};
use ref_cast::RefCast;
use super::node::ValueMut;
use crate::{
serde::tri,
value::{
node::{Value, ValueRefInner},
value_trait::JsonValueTrait,
},
};
#[derive(Debug, Eq, PartialEq, Clone, RefCast)]
#[repr(transparent)]
pub struct Array(pub(crate) Value);
impl Array {
#[inline]
pub fn into_value(self) -> Value {
self.0
}
#[inline]
pub const fn new() -> Self {
Array(Value::new_array())
}
#[inline]
pub fn with_capacity(capacity: usize) -> Self {
let mut array = Self::new();
array.reserve(capacity);
array
}
#[inline]
pub fn reserve(&mut self, additional: usize) {
self.0.reserve::<Value>(additional);
}
#[inline]
pub fn resize<T: Clone + Into<Value>>(&mut self, new_len: usize, value: T) {
if new_len > self.len() {
self.reserve(new_len - self.len());
for _ in self.len()..new_len {
self.push(value.clone().into());
}
} else {
self.truncate(new_len);
}
}
#[inline]
pub fn resize_with<F>(&mut self, new_len: usize, mut f: F)
where
F: FnMut() -> Value,
{
if new_len > self.len() {
self.reserve(new_len - self.len());
for _ in self.len()..new_len {
self.push(f());
}
} else {
self.truncate(new_len);
}
}
#[inline]
pub fn retain<F>(&mut self, mut f: F)
where
F: FnMut(&Value) -> bool,
{
self.retain_mut(|elem| f(elem));
}
#[inline]
pub fn split_off(&mut self, at: usize) -> Self {
if let ValueMut::Array(array) = self.0.as_mut() {
array.split_off(at).into()
} else {
panic!("Array::split_off: not an array");
}
}
#[inline]
pub fn swap_remove(&mut self, index: usize) -> Value {
let len = self.len();
assert!(index < len, "index {} out of bounds(len: {})", index, len);
if index != self.len() - 1 {
unsafe {
let src = self.as_mut_ptr().add(index);
let dst = self.as_mut_ptr().add(len - 1);
std::ptr::swap(src, dst);
}
}
self.pop().unwrap()
}
#[inline]
pub fn retain_mut<F>(&mut self, f: F)
where
F: FnMut(&mut Value) -> bool,
{
if let ValueMut::Array(array) = self.0.as_mut() {
array.retain_mut(f);
} else {
panic!("Array::retain_mut: not an array");
}
}
#[inline]
pub fn truncate(&mut self, len: usize) {
if let ValueMut::Array(array) = self.0.as_mut() {
array.truncate(len);
} else {
panic!("Array::truncate: not an array");
}
}
#[inline]
pub fn push<T: Into<Value>>(&mut self, val: T) {
if let ValueMut::Array(array) = self.0.as_mut() {
array.push(val.into());
} else {
panic!("Array::push: not an array");
}
}
#[inline]
pub fn pop(&mut self) -> Option<Value> {
debug_assert!(self.0.is_array());
self.0.pop()
}
#[inline]
pub fn len(&self) -> usize {
self.0
.as_value_slice()
.expect("call len in non-array type")
.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
#[inline]
pub fn as_mut_slice(&mut self) -> &mut [Value] {
self
}
#[inline]
pub fn as_slice(&self) -> &[Value] {
self
}
#[inline]
pub fn capacity(&self) -> usize {
self.0.capacity()
}
#[inline]
pub fn clear(&mut self) {
self.0.clear();
}
#[inline]
pub fn remove(&mut self, index: usize) {
self.0.remove_index(index);
}
#[inline]
pub fn append(&mut self, other: &mut Self) {
if let ValueMut::Array(array) = self.0.as_mut() {
if let ValueMut::Array(other_array) = other.0.as_mut() {
array.append(other_array);
} else {
panic!("Array::append: other is not an array");
}
} else {
panic!("Array::append: not an array");
}
}
#[inline]
pub fn drain<R>(&mut self, r: R) -> Drain<'_>
where
R: RangeBounds<usize>,
{
if let ValueMut::Array(array) = self.0.as_mut() {
array.drain(r)
} else {
panic!("Array::drain: not an array");
}
}
pub fn extend_from_within<R>(&mut self, src: R)
where
R: RangeBounds<usize>,
{
if let ValueMut::Array(array) = self.0.as_mut() {
array.extend_from_within(src);
} else {
panic!("Array::extend_from_within: not an array");
}
}
#[inline]
pub fn insert<T: Into<Value>>(&mut self, index: usize, element: T) {
if let ValueMut::Array(array) = self.0.as_mut() {
array.insert(index, element.into());
} else {
panic!("Array::insert: not an array");
}
}
}
impl Default for Array {
fn default() -> Self {
Self::new()
}
}
impl Deref for Array {
type Target = [Value];
fn deref(&self) -> &Self::Target {
self.0.as_value_slice().expect("Array::deref: not an array")
}
}
impl DerefMut for Array {
fn deref_mut(&mut self) -> &mut Self::Target {
if let ValueMut::Array(array) = self.0.as_mut() {
array
} else {
panic!("Array::deref_mut: not an array");
}
}
}
pub type Drain<'a> = std::vec::Drain<'a, Value>;
use std::{
ops::{Index, IndexMut},
slice::SliceIndex,
};
impl<I: SliceIndex<[Value]>> Index<I> for Array {
type Output = I::Output;
#[inline]
fn index(&self, index: I) -> &Self::Output {
Index::index(&**self, index)
}
}
impl<I: SliceIndex<[Value]>> IndexMut<I> for Array {
fn index_mut(&mut self, index: I) -> &mut Self::Output {
IndexMut::index_mut(&mut **self, index)
}
}
#[derive(Debug, Default, Clone)]
pub struct IntoIter {
array: Array,
index: usize,
len: usize,
}
impl IntoIter {
pub fn as_mut_slice(&mut self) -> &mut [Value] {
if let ValueMut::Array(array) = self.array.0.as_mut() {
unsafe {
let ptr = array.as_mut_ptr();
let len = array.len();
from_raw_parts_mut(ptr, len)
}
} else {
panic!("Array::as_mut_slice: not an array");
}
}
pub fn as_slice(&self) -> &[Value] {
if let ValueRefInner::Array(array) = self.array.0.as_ref2() {
unsafe {
let ptr = array.as_ptr();
let len = array.len();
from_raw_parts(ptr, len)
}
} else {
panic!("Array::as_slice: not an array");
}
}
}
impl AsRef<[Value]> for IntoIter {
fn as_ref(&self) -> &[Value] {
self.as_slice()
}
}
impl AsMut<[Value]> for IntoIter {
fn as_mut(&mut self) -> &mut [Value] {
self.as_mut_slice()
}
}
impl DoubleEndedIterator for IntoIter {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
if self.index < self.len {
self.len -= 1;
let value = self.array.0.get_index_mut(self.len).unwrap();
Some(value.take())
} else {
None
}
}
}
impl ExactSizeIterator for IntoIter {
#[inline]
fn len(&self) -> usize {
self.len - self.index
}
}
impl FusedIterator for IntoIter {}
impl Iterator for IntoIter {
type Item = Value;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
if self.index < self.len {
let value = self.array.0.get_index_mut(self.index).unwrap();
self.index += 1;
Some(value.take())
} else {
None
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.len - self.index;
(len, Some(len))
}
}
impl IntoIterator for Array {
type Item = Value;
type IntoIter = IntoIter;
#[inline]
fn into_iter(self) -> Self::IntoIter {
let len = self.len();
IntoIter {
array: self,
index: 0,
len,
}
}
}
impl<'a> IntoIterator for &'a Array {
type Item = &'a Value;
type IntoIter = std::slice::Iter<'a, Value>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a> IntoIterator for &'a mut Array {
type Item = &'a mut Value;
type IntoIter = std::slice::IterMut<'a, Value>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
impl serde::ser::Serialize for Array {
#[inline]
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: serde::ser::Serializer,
{
use serde::ser::SerializeSeq;
let mut seq = tri!(serializer.serialize_seq(Some(self.len())));
for v in self {
tri!(seq.serialize_element(v));
}
seq.end()
}
}
impl<'de> serde::de::Deserialize<'de> for Array {
#[inline]
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: serde::de::Deserializer<'de>,
{
let value: Value =
deserializer.deserialize_newtype_struct(super::de::TOKEN, super::de::ValueVisitor)?;
if value.is_array() {
Ok(Array(value))
} else {
Err(serde::de::Error::invalid_type(
serde::de::Unexpected::Other("not a array"),
&"array",
))
}
}
}
#[cfg(test)]
mod test {
use super::Array;
use crate::value::{node::Value, value_trait::JsonValueMutTrait};
#[test]
fn test_value_array() {
let mut val = crate::from_str::<Value>(r#"[1,2,3]"#).unwrap();
let array = val.as_array_mut().unwrap();
assert_eq!(array.len(), 3);
for i in 0..3 {
let old_len = array.len();
let new_node = Value::new_u64(i);
array.push(new_node);
assert_eq!(array.len(), old_len + 1);
let old_len = array.len();
let mut new_node = Array::default();
new_node.push(Value::new_u64(i));
array.push(new_node.0);
assert_eq!(array.len(), old_len + 1);
let old_len = array.len();
let mut new_node = Array::new();
new_node.push(Value::new_u64(i));
array.push(new_node.0);
assert_eq!(array.len(), old_len + 1);
}
for (i, v) in array.iter_mut().enumerate() {
*v = Value::new_u64(i as u64);
}
while !array.is_empty() {
dbg!(array.pop());
}
}
}