use super::{Entry, Table};
use crate::entry::Value;
use crate::error::{ParseStringError, UnknownError};
use crate::VdfError;
use serde_core::de::{DeserializeSeed, SeqAccess};
use serde_core::{Deserialize, Deserializer, Serialize, Serializer};
use std::ops::{Deref, DerefMut};
#[derive(Clone, PartialEq, Eq, Debug, Default)]
pub struct Array(Vec<Entry>);
impl Array {
pub(crate) fn from_space_separated(str: &str) -> Self {
let items = str
.split(' ')
.filter(|part| !part.is_empty())
.map(Value::from)
.map(Entry::from)
.collect();
Array(items)
}
}
impl<'de> Deserialize<'de> for Array {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
<Vec<Entry>>::deserialize(deserializer).map(Array)
}
}
impl Serialize for Array {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.0.serialize(serializer)
}
}
impl From<Vec<Entry>> for Array {
fn from(value: Vec<Entry>) -> Self {
Array(value)
}
}
impl From<Entry> for Array {
fn from(value: Entry) -> Self {
Array(vec![value])
}
}
impl From<Array> for Entry {
fn from(array: Array) -> Self {
Entry::Array(array)
}
}
impl Deref for Array {
type Target = Vec<Entry>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for Array {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
pub(crate) struct ArraySeq {
iter: std::vec::IntoIter<Entry>,
}
impl ArraySeq {
pub(crate) fn new(array: Array) -> Self {
ArraySeq {
iter: array.0.into_iter(),
}
}
}
impl<'de> SeqAccess<'de> for ArraySeq {
type Error = VdfError;
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
where
T: DeserializeSeed<'de>,
{
let next = match self.iter.next() {
Some(next) => next,
None => return Ok(None),
};
seed.deserialize(next).map(Some)
}
}
pub(crate) struct TableArraySeq {
iter: std::vec::IntoIter<(String, Entry)>,
last_key: Option<u64>,
}
impl TableArraySeq {
pub(crate) fn new(table: Table) -> Self {
let mut items: Vec<_> = table.into_iter().collect();
items.sort_by(|(key_a, _), (key_b, _)| key_a.cmp(key_b));
TableArraySeq {
iter: items.into_iter(),
last_key: None,
}
}
}
impl<'de> SeqAccess<'de> for TableArraySeq {
type Error = VdfError;
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
where
T: DeserializeSeed<'de>,
{
let (key, next) = match self.iter.next() {
Some(next) => next,
None => return Ok(None),
};
let key: u64 = key.parse().map_err(|_| {
VdfError::ParseString(ParseStringError {
ty: "u64",
value: key,
})
})?;
if let Some(last_key) = self.last_key {
let expected_key = last_key + 1;
if expected_key != key {
return Err(VdfError::Other(UnknownError::from(format!(
"Invalid array key {key}, expected {expected_key}"
))));
}
}
self.last_key = Some(key);
seed.deserialize(next).map(Some)
}
}