use crate::value::Value;
use crate::value::equivalent::Equivalent;
use crate::value::meta::Meta;
use crate::value::print::Print;
use crate::value::tracer::Tracer;
use ahash::HashSet;
use ahash::HashSetExt;
use serde::Deserialize;
use serde::Serialize;
#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct List {
#[serde(default, skip_serializing_if = "Tracer::is_empty")]
pub(crate) tracer: Tracer,
#[serde(default, skip_serializing_if = "Meta::is_empty")]
pub(crate) meta: Meta,
pub(crate) data: Vec<Value>,
}
impl core::fmt::Display for List {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str(&String::from_utf8_lossy(&self.clone().print_syntax()))
}
}
impl<V: Into<Value>> FromIterator<V> for List {
fn from_iter<T: IntoIterator<Item = V>>(iter: T) -> Self {
Self {
data: iter.into_iter().map(Into::into).collect(),
..Default::default()
}
}
}
impl From<Vec<Value>> for List {
fn from(value: Vec<Value>) -> Self {
Self {
data: value,
..Default::default()
}
}
}
impl From<List> for Vec<Value> {
fn from(value: List) -> Self {
value.data
}
}
impl IntoIterator for List {
type Item = Value;
type IntoIter = <Vec<Value> as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.data.into_iter()
}
}
impl List {
pub(crate) fn trace<T: Into<Tracer>>(&mut self, tracer: T) {
self.tracer.trace(tracer);
}
pub(crate) fn tracer(&self) -> &Tracer {
&self.tracer
}
pub fn with<V: Into<Value>>(mut self, value: V) -> Self {
self.data.push(value.into());
self
}
pub fn get(&self, index: usize) -> Option<&Value> {
self.data.get(index)
}
pub fn set(&mut self, index: usize, value: Value) {
self.data[index] = value;
}
pub fn push(&mut self, value: Value) {
self.data.push(value);
}
pub fn first(&self) -> Option<&Value> {
self.data.first()
}
pub fn last(&self) -> Option<&Value> {
self.data.last()
}
pub fn len(&self) -> usize {
self.data.len()
}
pub fn is_empty(&self) -> bool {
self.data.is_empty()
}
pub fn contains(&self, other: &Value) -> bool {
self.data.iter().any(|d| d.equivalent(other))
}
pub fn join(self) -> Vec<u8> {
self.data.into_iter().flat_map(Value::join).collect()
}
pub fn clear(mut self) -> Self {
self.data = Vec::default();
self
}
pub fn intersection(mut lists: Vec<List>) -> List {
if lists.is_empty() {
return List::default();
}
let mut data = lists.remove(0).data;
data.retain(|d| lists.iter().all(|v| v.contains(d)));
data.into_iter().collect()
}
pub fn union(lists: Vec<List>) -> List {
let len = lists.first().map(|v| v.data.len()).unwrap_or_default();
let mut data = Vec::with_capacity(len);
let mut seen = HashSet::<Vec<u8>>::with_capacity(len);
for list in lists {
for value in list.data {
if seen.insert(value.clone().join()) {
data.push(value);
}
}
}
data.into_iter().collect()
}
pub(crate) fn fold(&mut self, mut value: Self) {
match value.meta.get(b"internal-insert") {
Some(b"prepend") => {
value.data.append(&mut self.data);
self.data = value.data;
}
Some(b"append") => {
self.data.append(&mut value.data);
}
_ => {
*self = value;
}
}
}
}