use crate::{JsonCodeMap, JsonFragment, JsonValue, code_map::JsonMapped};
pub type JsonArray = [JsonValue];
pub type JsonArrayBuf = Vec<JsonValue>;
pub trait JsonArrayExt {
fn iter_mapped<'m>(&self, code_map: &'m JsonCodeMap, offset: usize) -> IterMapped<'_, 'm>;
fn get_fragment(&self, index: usize) -> Result<JsonFragment<'_>, usize>;
}
pub trait JsonArrayBufExt: Sized + JsonArrayExt {
fn into_iter_mapped<'m>(self, code_map: &'m JsonCodeMap, offset: usize) -> IntoIterMapped<'m>;
}
impl JsonArrayExt for JsonArray {
fn iter_mapped<'m>(&self, code_map: &'m JsonCodeMap, offset: usize) -> IterMapped<'_, 'm> {
IterMapped {
items: self.iter(),
code_map,
offset: offset + 1,
}
}
fn get_fragment(&self, mut index: usize) -> Result<JsonFragment<'_>, usize> {
for v in self {
match v.get_fragment(index) {
Ok(value) => return Ok(value),
Err(i) => index = i,
}
}
Err(index)
}
}
impl JsonArrayExt for JsonArrayBuf {
fn iter_mapped<'m>(&self, code_map: &'m JsonCodeMap, offset: usize) -> IterMapped<'_, 'm> {
self.as_slice().iter_mapped(code_map, offset)
}
fn get_fragment(&self, index: usize) -> Result<JsonFragment<'_>, usize> {
self.as_slice().get_fragment(index)
}
}
impl JsonArrayBufExt for JsonArrayBuf {
fn into_iter_mapped<'m>(self, code_map: &'m JsonCodeMap, offset: usize) -> IntoIterMapped<'m> {
IntoIterMapped {
items: self.into_iter(),
code_map,
offset: offset + 1,
}
}
}
pub struct IterMapped<'a, 'm> {
items: std::slice::Iter<'a, JsonValue>,
code_map: &'m JsonCodeMap,
offset: usize,
}
impl<'a, 'm> Iterator for IterMapped<'a, 'm> {
type Item = JsonMapped<&'a JsonValue>;
fn next(&mut self) -> Option<Self::Item> {
self.items.next().map(|item| {
let offset = self.offset;
self.offset += self.code_map.get(self.offset).unwrap().volume;
JsonMapped(item, offset)
})
}
}
pub struct IntoIterMapped<'m> {
items: std::vec::IntoIter<JsonValue>,
code_map: &'m JsonCodeMap,
offset: usize,
}
impl<'m> Iterator for IntoIterMapped<'m> {
type Item = JsonMapped<JsonValue>;
fn next(&mut self) -> Option<Self::Item> {
self.items.next().map(|item| {
let offset = self.offset;
self.offset += self.code_map.get(self.offset).unwrap().volume;
JsonMapped(item, offset)
})
}
}