use {
crate::{
errors::IqInternalError,
*,
},
serde::{
Serialize,
ser,
},
};
pub(crate) struct Diver<'p> {
keys: &'p [&'p str],
next_token: usize,
requested_seq_idx: usize,
current_seq_idx: usize,
return_next_primitive: bool,
accept_next_map_value: bool,
return_next_map_value: bool,
format: IqFormat,
}
impl<'p> Diver<'p> {
pub fn new(
keys: &'p [&'p str],
format: IqFormat,
) -> Self {
Self {
keys,
next_token: 0,
requested_seq_idx: 0,
current_seq_idx: 0,
return_next_primitive: false,
return_next_map_value: false,
accept_next_map_value: false,
format,
}
}
pub fn set_return_next_primitive(&mut self) {
self.return_next_primitive = true;
}
fn has_next_token(
&self,
key: &str,
) -> bool {
self.next_token < self.keys.len() && key == self.keys[self.next_token]
}
fn on_found_with_value<T>(
&mut self,
value: &T,
) -> Result<(), IqInternalError>
where
T: ?Sized + Serialize,
{
match self.format {
IqFormat::Primitive => {
self.return_next_primitive = true;
Ok(())
}
IqFormat::Json => {
let json = serde_json::to_string(value)?;
Err(IqInternalError::Found(json))
}
IqFormat::JsonPretty => {
let json = serde_json::to_string_pretty(value)?;
Err(IqInternalError::Found(json))
}
IqFormat::Size => match Sizer::count(value) {
Some(count) => Err(IqInternalError::Count(count)),
None => Err(IqInternalError::NoCount),
},
}
}
fn incr_next_token_with_value<T>(
&mut self,
value: &T,
) -> Result<(), IqInternalError>
where
T: ?Sized + Serialize,
{
self.next_token += 1;
if self.next_token >= self.keys.len() {
return self.on_found_with_value(value);
}
Ok(())
}
}
impl ser::Serializer for &mut Diver<'_> {
type Ok = ();
type Error = IqInternalError;
type SerializeSeq = Self;
type SerializeTuple = Self;
type SerializeTupleStruct = Self;
type SerializeTupleVariant = Self;
type SerializeMap = Self;
type SerializeStruct = Self;
type SerializeStructVariant = Self;
fn serialize_bool(
self,
v: bool,
) -> Result<(), IqInternalError> {
if self.return_next_primitive {
return Err(IqInternalError::Found(format!("{}", v)));
}
Ok(())
}
fn serialize_i8(
self,
v: i8,
) -> Result<(), IqInternalError> {
if self.return_next_primitive {
return Err(IqInternalError::Found(format!("{}", v)));
}
Ok(())
}
fn serialize_i16(
self,
v: i16,
) -> Result<(), IqInternalError> {
if self.return_next_primitive {
return Err(IqInternalError::Found(format!("{}", v)));
}
Ok(())
}
fn serialize_i32(
self,
v: i32,
) -> Result<(), IqInternalError> {
if self.return_next_primitive {
return Err(IqInternalError::Found(format!("{}", v)));
}
Ok(())
}
fn serialize_i64(
self,
v: i64,
) -> Result<(), IqInternalError> {
if self.return_next_primitive {
return Err(IqInternalError::Found(format!("{}", v)));
}
Ok(())
}
fn serialize_u8(
self,
v: u8,
) -> Result<(), IqInternalError> {
if self.return_next_primitive {
return Err(IqInternalError::Found(format!("{}", v)));
}
Ok(())
}
fn serialize_u16(
self,
v: u16,
) -> Result<(), IqInternalError> {
if self.return_next_primitive {
return Err(IqInternalError::Found(format!("{}", v)));
}
Ok(())
}
fn serialize_u32(
self,
v: u32,
) -> Result<(), IqInternalError> {
if self.return_next_primitive {
return Err(IqInternalError::Found(format!("{}", v)));
}
Ok(())
}
fn serialize_u64(
self,
v: u64,
) -> Result<(), IqInternalError> {
if self.return_next_primitive {
return Err(IqInternalError::Found(format!("{}", v)));
}
Ok(())
}
fn serialize_f32(
self,
v: f32,
) -> Result<(), IqInternalError> {
if self.return_next_primitive {
return Err(IqInternalError::Found(format!("{}", v)));
}
Ok(())
}
fn serialize_f64(
self,
v: f64,
) -> Result<(), IqInternalError> {
if self.return_next_primitive {
return Err(IqInternalError::Found(format!("{}", v)));
}
Ok(())
}
fn serialize_char(
self,
v: char,
) -> Result<(), IqInternalError> {
if self.return_next_primitive {
return Err(IqInternalError::Found(format!("{}", v)));
}
Ok(())
}
fn serialize_str(
self,
v: &str,
) -> Result<(), IqInternalError> {
if self.return_next_primitive {
return Err(IqInternalError::Found(v.to_string()));
}
Ok(())
}
fn serialize_bytes(
self,
_v: &[u8],
) -> Result<(), IqInternalError> {
Ok(())
}
fn serialize_none(self) -> Result<(), IqInternalError> {
if self.return_next_primitive {
return Err(IqInternalError::Found("none".to_string()));
}
Ok(())
}
fn serialize_some<T>(
self,
value: &T,
) -> Result<(), IqInternalError>
where
T: ?Sized + Serialize,
{
value.serialize(self)
}
fn serialize_unit(self) -> Result<(), IqInternalError> {
if self.return_next_primitive {
return Err(IqInternalError::Found("unit".to_string()));
}
Ok(())
}
fn serialize_unit_struct(
self,
_name: &'static str,
) -> Result<(), IqInternalError> {
self.serialize_unit()
}
fn serialize_unit_variant(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
) -> Result<(), IqInternalError> {
if self.return_next_primitive {
return Err(IqInternalError::Found(variant.to_string()));
}
self.serialize_str(variant)
}
fn serialize_newtype_struct<T>(
self,
_name: &'static str,
value: &T,
) -> Result<(), IqInternalError>
where
T: ?Sized + Serialize,
{
value.serialize(self)
}
fn serialize_newtype_variant<T>(
self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
value: &T,
) -> Result<(), IqInternalError>
where
T: ?Sized + Serialize,
{
value.serialize(&mut *self)?;
Ok(())
}
fn serialize_seq(
self,
len: Option<usize>,
) -> Result<Self::SerializeSeq, IqInternalError> {
let requested_idx = self
.keys
.get(self.next_token)
.ok_or(IqInternalError::OutOfBounds)?;
if requested_idx.len() > 1 && requested_idx.as_bytes()[0] == b'-' {
if let Some(len) = len {
let abs: usize = requested_idx[1..]
.parse()
.map_err(|_| IqInternalError::IndexExpected)?;
if abs > len {
return Err(IqInternalError::OutOfBounds);
}
self.requested_seq_idx = len - abs;
} else {
return Err(IqInternalError::LengthRequired);
}
} else {
self.requested_seq_idx = self
.keys
.get(self.next_token)
.ok_or(IqInternalError::OutOfBounds)?
.parse()
.map_err(|_| IqInternalError::IndexExpected)?;
}
self.current_seq_idx = 0;
Ok(self)
}
fn serialize_tuple(
self,
len: usize,
) -> Result<Self::SerializeTuple, IqInternalError> {
self.serialize_seq(Some(len))
}
fn serialize_tuple_struct(
self,
_name: &'static str,
len: usize,
) -> Result<Self::SerializeTupleStruct, IqInternalError> {
self.serialize_seq(Some(len))
}
fn serialize_tuple_variant(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleVariant, IqInternalError> {
variant.serialize(&mut *self)?;
Ok(self)
}
fn serialize_map(
self,
_len: Option<usize>,
) -> Result<Self::SerializeMap, IqInternalError> {
Ok(self)
}
fn serialize_struct(
self,
_name: &'static str,
len: usize,
) -> Result<Self::SerializeStruct, IqInternalError> {
self.serialize_map(Some(len))
}
fn serialize_struct_variant(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
_len: usize,
) -> Result<Self::SerializeStructVariant, IqInternalError> {
variant.serialize(&mut *self)?;
Ok(self)
}
}
impl ser::SerializeSeq for &mut Diver<'_> {
type Ok = ();
type Error = IqInternalError;
fn serialize_element<T>(
&mut self,
value: &T,
) -> Result<(), IqInternalError>
where
T: ?Sized + Serialize,
{
if self.current_seq_idx == self.requested_seq_idx {
self.incr_next_token_with_value(value)?;
value.serialize(&mut **self)?;
}
self.current_seq_idx += 1;
Ok(())
}
fn end(self) -> Result<(), IqInternalError> {
Ok(())
}
}
impl ser::SerializeTuple for &mut Diver<'_> {
type Ok = ();
type Error = IqInternalError;
fn serialize_element<T>(
&mut self,
value: &T,
) -> Result<(), IqInternalError>
where
T: ?Sized + Serialize,
{
if self.current_seq_idx == self.requested_seq_idx {
self.incr_next_token_with_value(value)?;
value.serialize(&mut **self)?;
}
self.current_seq_idx += 1;
Ok(())
}
fn end(self) -> Result<(), IqInternalError> {
Ok(())
}
}
impl ser::SerializeTupleStruct for &mut Diver<'_> {
type Ok = ();
type Error = IqInternalError;
fn serialize_field<T>(
&mut self,
value: &T,
) -> Result<(), IqInternalError>
where
T: ?Sized + Serialize,
{
if self.current_seq_idx == self.requested_seq_idx {
self.incr_next_token_with_value(value)?;
value.serialize(&mut **self)?;
}
self.current_seq_idx += 1;
Ok(())
}
fn end(self) -> Result<(), IqInternalError> {
Ok(())
}
}
impl ser::SerializeTupleVariant for &mut Diver<'_> {
type Ok = ();
type Error = IqInternalError;
fn serialize_field<T>(
&mut self,
value: &T,
) -> Result<(), IqInternalError>
where
T: ?Sized + Serialize,
{
value.serialize(&mut **self)
}
fn end(self) -> Result<(), IqInternalError> {
Ok(())
}
}
impl ser::SerializeMap for &mut Diver<'_> {
type Ok = ();
type Error = IqInternalError;
fn serialize_key<T>(
&mut self,
_key: &T,
) -> Result<(), IqInternalError>
where
T: ?Sized + Serialize,
{
let key = serde_json::to_string(_key)?;
self.accept_next_map_value = self.next_token < self.keys.len()
&& key.trim_matches('"') == self.keys[self.next_token].trim_matches('"');
if self.accept_next_map_value {
self.next_token += 1;
if self.next_token >= self.keys.len() {
self.return_next_map_value = true;
}
}
Ok(())
}
fn serialize_value<T>(
&mut self,
value: &T,
) -> Result<(), IqInternalError>
where
T: ?Sized + Serialize,
{
if !self.accept_next_map_value {
return Ok(());
}
if self.return_next_map_value {
self.on_found_with_value(value)?;
}
value.serialize(&mut **self)
}
fn end(self) -> Result<(), IqInternalError> {
Ok(())
}
}
impl ser::SerializeStruct for &mut Diver<'_> {
type Ok = ();
type Error = IqInternalError;
fn serialize_field<T>(
&mut self,
key: &'static str,
value: &T,
) -> Result<(), IqInternalError>
where
T: ?Sized + Serialize,
{
if self.has_next_token(key) {
self.incr_next_token_with_value(value)?;
value.serialize(&mut **self)?;
}
Ok(())
}
fn end(self) -> Result<(), IqInternalError> {
Ok(())
}
}
impl ser::SerializeStructVariant for &mut Diver<'_> {
type Ok = ();
type Error = IqInternalError;
fn serialize_field<T>(
&mut self,
key: &'static str,
value: &T,
) -> Result<(), IqInternalError>
where
T: ?Sized + Serialize,
{
if self.has_next_token(key) {
self.incr_next_token_with_value(value)?;
}
value.serialize(&mut **self)
}
fn end(self) -> Result<(), IqInternalError> {
Ok(())
}
}