url_params_serializer 0.1.1

Allows serialization of types to URL GET parameters
Documentation
use serde::ser::Serialize;
use std::ops::AddAssign;

use crate::param_segment::ParamSegment;
use crate::param_serializer_trait::ParamSerializer;
use crate::serializer_wrapper::Wrap;

pub struct MapSer {
    seq_ser: Option<SeqSer>,
    key_stack: Vec<ParamSegment>,
    pub pairs: Vec<(String, String)>,
}

struct SeqSer {
    val: ParamSegment,
    depth: usize,
}

impl MapSer {
    pub fn new() -> Self {
        MapSer {
            seq_ser: None,
            key_stack: Vec::new(),
            pairs: Vec::new(),
        }
    }

    fn add_param<T>(&mut self, v: T)
    where
        ParamSegment: AddAssign<T>,
    {
        let key = {
            let mut key = ParamSegment(None);
            let mut first = true;

            if self.key_stack.is_empty() {
                panic!()
            }

            for k in self.key_stack.iter() {
                if !first {
                    AddAssign::<char>::add_assign(&mut key, '.');
                }

                first = false;

                AddAssign::<&ParamSegment>::add_assign(&mut key, k);
            }

            key
        };

        let val = {
            let mut val = ParamSegment(None);
            val += v;
            val
        };

        self.pairs.push((key.into(), val.into()));
    }
}

impl SeqSer {
    fn append_value<T>(&mut self, v: T)
    where
        ParamSegment: AddAssign<T>,
    {
        if let ParamSegment(Some(_)) = self.val {
            AddAssign::<char>::add_assign(&mut self.val, ',');
        }

        self.val += v;
    }
}

impl ParamSerializer for MapSer {
    fn push_key(&mut self, v: impl Serialize) {
        let key = {
            let mut key = Wrap(ParamSegment(None));
            v.serialize(&mut key).unwrap();
            key.0
        };
        self.key_stack.push(key);
    }

    fn pop_key(&mut self) {
        self.key_stack.pop().unwrap();
    }

    fn add_value<T>(&mut self, v: T)
    where
        ParamSegment: AddAssign<T>,
    {
        if let Some(seq_ser) = self.seq_ser.as_mut() {
            seq_ser.append_value(v);
        } else {
            self.add_param(v);
        }
    }

    fn start_seq(&mut self) {
        if self.key_stack.is_empty() {
            panic!("Cannot serialize a sequence as query parameters, unless it is within a map, struct, or enum variant");
        }

        if let Some(seq_ser) = self.seq_ser.as_mut() {
            seq_ser.depth += 1;
        } else {
            self.seq_ser = Some(SeqSer {
                val: ParamSegment(None),
                depth: 1,
            });
        }
    }

    fn end_seq(&mut self) {
        let finished = {
            let seq_ser = self.seq_ser.as_mut().unwrap();
            seq_ser.depth -= 1;
            seq_ser.depth == 0
        };

        if finished {
            let seq_ser = self.seq_ser.take().unwrap();
            self.add_param(seq_ser.val);
        }
    }

    fn start_map(&mut self) {
        if self.seq_ser.is_some() {
            panic!("Cannot serialize complex types within a sequence as query parameters");
        }
    }
}