use std::fmt;
use bytes::{BufMut, BytesMut};
use crate::{
validators::{validate_param_key, validate_param_value},
Error
};
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct KeyValue {
key: String,
value: String
}
#[derive(Debug, Clone, Default)]
pub struct KVLines {
lines: Vec<KeyValue>
}
impl KVLines {
#[must_use]
pub fn new() -> Self {
Self::default()
}
pub fn clear(&mut self) {
self.lines.clear();
}
#[must_use]
pub const fn get_inner(&self) -> &Vec<KeyValue> {
&self.lines
}
#[allow(clippy::needless_pass_by_value)]
pub fn append(
&mut self,
key: impl ToString,
value: impl ToString
) -> Result<(), Error> {
let key = key.to_string();
let value = value.to_string();
validate_param_key(&key)?;
validate_param_value(&value)?;
self.lines.push(KeyValue { key, value });
Ok(())
}
#[must_use]
pub fn calc_buf_size(&self) -> usize {
let mut size = 0;
for n in &self.lines {
size += n.key.len() + 1; size += n.value.len() + 1; }
size + 1 }
#[must_use]
pub fn serialize(&self) -> Vec<u8> {
let mut buf = Vec::new();
for n in &self.lines {
let k = n.key.as_bytes();
let v = n.value.as_bytes();
for a in k {
buf.push(*a);
}
buf.push(b' ');
for a in v {
buf.push(*a);
}
buf.push(b'\n');
}
buf.push(b'\n');
buf
}
pub fn encoder_write(&self, buf: &mut BytesMut) {
let size = self.calc_buf_size();
buf.reserve(size);
for n in &self.lines {
buf.put(n.key.as_bytes());
buf.put_u8(b' ');
buf.put(n.value.as_bytes());
buf.put_u8(b'\n');
}
buf.put_u8(b'\n');
}
#[must_use]
pub fn into_inner(self) -> Vec<KeyValue> {
self.lines
}
}
impl From<Vec<KeyValue>> for KVLines {
fn from(lines: Vec<KeyValue>) -> Self {
Self { lines }
}
}
impl TryFrom<Vec<(String, String)>> for KVLines {
type Error = Error;
fn try_from(lines: Vec<(String, String)>) -> Result<Self, Self::Error> {
let mut out = Self { lines: Vec::new() };
for (key, value) in lines {
out.append(key, value)?;
}
Ok(out)
}
}
impl fmt::Display for KVLines {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut kvlist = Vec::new();
for n in &self.lines {
kvlist.push(format!("{}={}", n.key, n.value));
}
write!(f, "{{{}}}", kvlist.join(","))
}
}