use std::fmt;
use serde::{ser, de};
use serde::de::{Visitor, Error as _};
use serde::ser::{Serialize, SerializeSeq};
use crate::{CommandData, AttrValue, PropertyValue};
impl<'de> de::Deserialize<'de> for CommandData {
#[inline]
fn deserialize<D: de::Deserializer<'de>>(deser: D) -> Result<CommandData, D::Error> {
struct ValueVisitor;
impl<'de> Visitor<'de> for ValueVisitor {
type Value = CommandData;
#[inline]
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a CommandData value")
}
#[inline]
fn visit_bool<E>(self, value: bool) -> Result<CommandData, E> {
Ok(CommandData::Boolean(value))
}
#[inline]
fn visit_i16<E>(self, value: i16) -> Result<CommandData, E> {
Ok(CommandData::Short(value))
}
#[inline]
fn visit_i32<E>(self, value: i32) -> Result<CommandData, E> {
Ok(CommandData::Long(value))
}
#[inline]
fn visit_i64<E>(self, value: i64) -> Result<CommandData, E> {
Ok(CommandData::Long64(value))
}
#[inline]
fn visit_u16<E>(self, value: u16) -> Result<CommandData, E> {
Ok(CommandData::UShort(value))
}
#[inline]
fn visit_u32<E>(self, value: u32) -> Result<CommandData, E> {
Ok(CommandData::ULong(value))
}
#[inline]
fn visit_u64<E>(self, value: u64) -> Result<CommandData, E> {
Ok(CommandData::ULong64(value))
}
#[inline]
fn visit_f32<E>(self, value: f32) -> Result<CommandData, E> {
Ok(CommandData::Float(value))
}
#[inline]
fn visit_f64<E>(self, value: f64) -> Result<CommandData, E> {
Ok(CommandData::Double(value))
}
#[inline]
fn visit_str<E: de::Error>(self, value: &str) -> Result<CommandData, E> {
Ok(CommandData::String(value.as_bytes().to_vec()))
}
#[inline]
fn visit_string<E>(self, value: String) -> Result<CommandData, E> {
Ok(CommandData::String(value.into_bytes()))
}
#[inline]
fn visit_bytes<E: de::Error>(self, value: &[u8]) -> Result<CommandData, E> {
Ok(CommandData::CharArray(value.to_vec()))
}
#[inline]
fn visit_byte_buf<E: de::Error>(self, value: Vec<u8>) -> Result<CommandData, E> {
Ok(CommandData::CharArray(value))
}
#[inline]
fn visit_none<E>(self) -> Result<CommandData, E> {
Ok(CommandData::Void)
}
#[inline]
fn visit_some<D: de::Deserializer<'de>>(self, deser: D) -> Result<CommandData, D::Error> {
de::Deserialize::deserialize(deser)
}
#[inline]
fn visit_unit<E>(self) -> Result<CommandData, E> {
Ok(CommandData::Void)
}
#[inline]
fn visit_seq<V: de::SeqAccess<'de>>(self, mut visitor: V) -> Result<CommandData, V::Error> {
macro_rules! get_array {
($v:ident, $alt:ident, $arralt:ident) => {
{
let mut values = Vec::new();
values.push($v);
while let Some(el) = visitor.next_element()? {
match el {
CommandData::$alt(v) => values.push(v),
_ => Err(V::Error::custom("array elements must have same type"))?,
}
}
Ok(CommandData::$arralt(values))
}
}
}
match visitor.next_element()? {
None => Ok(CommandData::DoubleArray(vec![])),
Some(val) => match val {
CommandData::Boolean(v) => get_array!(v, Boolean, BooleanArray),
CommandData::Short(v) => get_array!(v, Short, ShortArray),
CommandData::Long(v) => get_array!(v, Long, LongArray),
CommandData::Long64(v) => get_array!(v, Long64, Long64Array),
CommandData::UShort(v) => get_array!(v, UShort, UShortArray),
CommandData::ULong(v) => get_array!(v, ULong, ULongArray),
CommandData::ULong64(v) => get_array!(v, ULong64, ULong64Array),
CommandData::Float(v) => get_array!(v, Float, FloatArray),
CommandData::Double(v) => get_array!(v, Double, DoubleArray),
CommandData::String(v) => get_array!(v, String, StringArray),
CommandData::LongArray(v) => match (visitor.next_element()?,
visitor.next_element()?) {
(Some(CommandData::StringArray(w)), None::<CommandData>) =>
Ok(CommandData::LongStringArray(v, w)),
_ => Err(V::Error::custom("invalid type inside array")),
}
CommandData::DoubleArray(v) => match (visitor.next_element()?,
visitor.next_element()?) {
(Some(CommandData::StringArray(w)), None::<CommandData>) =>
Ok(CommandData::DoubleStringArray(v, w)),
_ => Err(V::Error::custom("invalid type inside array")),
}
_ => Err(V::Error::custom("invalid type inside array")),
}
}
}
}
deser.deserialize_any(ValueVisitor)
}
}
impl<'de> de::Deserialize<'de> for AttrValue {
#[inline]
fn deserialize<D: de::Deserializer<'de>>(deser: D) -> Result<AttrValue, D::Error> {
struct ValueVisitor;
impl<'de> Visitor<'de> for ValueVisitor {
type Value = AttrValue;
#[inline]
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a AttrValue value")
}
#[inline]
fn visit_bool<E>(self, value: bool) -> Result<AttrValue, E> {
Ok(AttrValue::Boolean(value))
}
#[inline]
fn visit_i16<E>(self, value: i16) -> Result<AttrValue, E> {
Ok(AttrValue::Short(value))
}
#[inline]
fn visit_i32<E>(self, value: i32) -> Result<AttrValue, E> {
Ok(AttrValue::Long(value))
}
#[inline]
fn visit_i64<E>(self, value: i64) -> Result<AttrValue, E> {
Ok(AttrValue::Long64(value))
}
#[inline]
fn visit_u16<E>(self, value: u16) -> Result<AttrValue, E> {
Ok(AttrValue::UShort(value))
}
#[inline]
fn visit_u32<E>(self, value: u32) -> Result<AttrValue, E> {
Ok(AttrValue::ULong(value))
}
#[inline]
fn visit_u64<E>(self, value: u64) -> Result<AttrValue, E> {
Ok(AttrValue::ULong64(value))
}
#[inline]
fn visit_f32<E>(self, value: f32) -> Result<AttrValue, E> {
Ok(AttrValue::Float(value))
}
#[inline]
fn visit_f64<E>(self, value: f64) -> Result<AttrValue, E> {
Ok(AttrValue::Double(value))
}
#[inline]
fn visit_str<E: de::Error>(self, value: &str) -> Result<AttrValue, E> {
Ok(AttrValue::String(value.as_bytes().to_vec()))
}
#[inline]
fn visit_string<E>(self, value: String) -> Result<AttrValue, E> {
Ok(AttrValue::String(value.into_bytes()))
}
#[inline]
fn visit_bytes<E: de::Error>(self, value: &[u8]) -> Result<AttrValue, E> {
Ok(AttrValue::UCharArray(value.to_vec()))
}
#[inline]
fn visit_byte_buf<E: de::Error>(self, value: Vec<u8>) -> Result<AttrValue, E> {
Ok(AttrValue::UCharArray(value))
}
#[inline]
fn visit_some<D: de::Deserializer<'de>>(self, deser: D) -> Result<AttrValue, D::Error> {
de::Deserialize::deserialize(deser)
}
#[inline]
fn visit_seq<V: de::SeqAccess<'de>>(self, mut visitor: V) -> Result<AttrValue, V::Error> {
macro_rules! get_array {
($v:ident, $alt:ident, $arralt:ident) => {
{
let mut values = Vec::new();
values.push($v);
while let Some(el) = visitor.next_element()? {
match el {
AttrValue::$alt(v) => values.push(v),
_ => Err(V::Error::custom("array elements must have same type"))?,
}
}
Ok(AttrValue::$arralt(values))
}
}
}
match visitor.next_element()? {
None => Ok(AttrValue::DoubleArray(vec![])),
Some(val) => match val {
AttrValue::Boolean(v) => get_array!(v, Boolean, BooleanArray),
AttrValue::Short(v) => get_array!(v, Short, ShortArray),
AttrValue::Long(v) => get_array!(v, Long, LongArray),
AttrValue::Long64(v) => get_array!(v, Long64, Long64Array),
AttrValue::UShort(v) => get_array!(v, UShort, UShortArray),
AttrValue::ULong(v) => get_array!(v, ULong, ULongArray),
AttrValue::ULong64(v) => get_array!(v, ULong64, ULong64Array),
AttrValue::Float(v) => get_array!(v, Float, FloatArray),
AttrValue::Double(v) => get_array!(v, Double, DoubleArray),
AttrValue::String(v) => get_array!(v, String, StringArray),
_ => Err(V::Error::custom("invalid type inside array")),
}
}
}
}
deser.deserialize_any(ValueVisitor)
}
}
impl<'de> de::Deserialize<'de> for PropertyValue {
#[inline]
fn deserialize<D: de::Deserializer<'de>>(deser: D) -> Result<PropertyValue, D::Error> {
struct ValueVisitor;
impl<'de> Visitor<'de> for ValueVisitor {
type Value = PropertyValue;
#[inline]
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a PropertyValue value")
}
#[inline]
fn visit_bool<E>(self, value: bool) -> Result<PropertyValue, E> {
Ok(PropertyValue::Boolean(value))
}
#[inline]
fn visit_i16<E>(self, value: i16) -> Result<PropertyValue, E> {
Ok(PropertyValue::Short(value))
}
#[inline]
fn visit_i32<E>(self, value: i32) -> Result<PropertyValue, E> {
Ok(PropertyValue::Long(value))
}
#[inline]
fn visit_i64<E>(self, value: i64) -> Result<PropertyValue, E> {
Ok(PropertyValue::Long64(value))
}
#[inline]
fn visit_u16<E>(self, value: u16) -> Result<PropertyValue, E> {
Ok(PropertyValue::UShort(value))
}
#[inline]
fn visit_u32<E>(self, value: u32) -> Result<PropertyValue, E> {
Ok(PropertyValue::ULong(value))
}
#[inline]
fn visit_u64<E>(self, value: u64) -> Result<PropertyValue, E> {
Ok(PropertyValue::ULong64(value))
}
#[inline]
fn visit_f32<E>(self, value: f32) -> Result<PropertyValue, E> {
Ok(PropertyValue::Float(value))
}
#[inline]
fn visit_f64<E>(self, value: f64) -> Result<PropertyValue, E> {
Ok(PropertyValue::Double(value))
}
#[inline]
fn visit_str<E: de::Error>(self, value: &str) -> Result<PropertyValue, E> {
Ok(PropertyValue::String(value.as_bytes().to_vec()))
}
#[inline]
fn visit_string<E>(self, value: String) -> Result<PropertyValue, E> {
Ok(PropertyValue::String(value.into_bytes()))
}
#[inline]
fn visit_some<D: de::Deserializer<'de>>(self, deser: D) -> Result<PropertyValue, D::Error> {
de::Deserialize::deserialize(deser)
}
#[inline]
fn visit_seq<V: de::SeqAccess<'de>>(self, mut visitor: V) -> Result<PropertyValue, V::Error> {
macro_rules! get_array {
($v:ident, $alt:ident, $arralt:ident) => {
{
let mut values = Vec::new();
values.push($v);
while let Some(el) = visitor.next_element()? {
match el {
PropertyValue::$alt(v) => values.push(v),
_ => Err(V::Error::custom("array elements must have same type"))?,
}
}
Ok(PropertyValue::$arralt(values))
}
}
}
match visitor.next_element()? {
None => Ok(PropertyValue::DoubleArray(vec![])),
Some(val) => match val {
PropertyValue::Short(v) => get_array!(v, Short, ShortArray),
PropertyValue::Long(v) => get_array!(v, Long, LongArray),
PropertyValue::Long64(v) => get_array!(v, Long64, Long64Array),
PropertyValue::UShort(v) => get_array!(v, UShort, UShortArray),
PropertyValue::ULong(v) => get_array!(v, ULong, ULongArray),
PropertyValue::ULong64(v) => get_array!(v, ULong64, ULong64Array),
PropertyValue::Float(v) => get_array!(v, Float, FloatArray),
PropertyValue::Double(v) => get_array!(v, Double, DoubleArray),
PropertyValue::String(v) => get_array!(v, String, StringArray),
_ => Err(V::Error::custom("invalid type inside array")),
}
}
}
}
deser.deserialize_any(ValueVisitor)
}
}
struct StringSeq<'a>(&'a Vec<Vec<u8>>);
impl<'a> Serialize for StringSeq<'a> {
fn serialize<S: ser::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
let mut seq = s.serialize_seq(Some(self.0.len()))?;
for el in self.0 {
match std::str::from_utf8(el) {
Ok(vs) => seq.serialize_element(vs),
Err(_) => seq.serialize_element(el)
}?;
}
seq.end()
}
}
impl Serialize for CommandData {
fn serialize<S: ser::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
match self {
CommandData::Void => s.serialize_unit(),
CommandData::Boolean(v) => s.serialize_bool(*v),
CommandData::Short(v) => s.serialize_i16(*v),
CommandData::Long(v) => s.serialize_i32(*v),
CommandData::Long64(v) => s.serialize_i64(*v),
CommandData::UShort(v) => s.serialize_u16(*v),
CommandData::ULong(v) => s.serialize_u32(*v),
CommandData::ULong64(v) => s.serialize_u64(*v),
CommandData::Float(v) => s.serialize_f32(*v),
CommandData::Double(v) => s.serialize_f64(*v),
CommandData::String(v) => match std::str::from_utf8(v) {
Ok(vs) => s.serialize_str(vs),
Err(_) => s.serialize_bytes(v)
},
CommandData::State(v) => s.serialize_str(&v.to_string()),
CommandData::Encoded(v) => v.serialize(s),
CommandData::BooleanArray(v) => s.collect_seq(v),
CommandData::CharArray(v) => s.collect_seq(v),
CommandData::ShortArray(v) => s.collect_seq(v),
CommandData::LongArray(v) => s.collect_seq(v),
CommandData::Long64Array(v) => s.collect_seq(v),
CommandData::UShortArray(v) => s.collect_seq(v),
CommandData::ULongArray(v) => s.collect_seq(v),
CommandData::ULong64Array(v) => s.collect_seq(v),
CommandData::FloatArray(v) => s.collect_seq(v),
CommandData::DoubleArray(v) => s.collect_seq(v),
CommandData::StringArray(v) => StringSeq(v).serialize(s),
CommandData::LongStringArray(v, w) => {
let mut seq = s.serialize_seq(Some(2))?;
seq.serialize_element(v)?;
seq.serialize_element(&StringSeq(w))?;
seq.end()
}
CommandData::DoubleStringArray(v, w) => {
let mut seq = s.serialize_seq(Some(2))?;
seq.serialize_element(v)?;
seq.serialize_element(&StringSeq(w))?;
seq.end()
}
}
}
}
impl Serialize for AttrValue {
fn serialize<S: ser::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
match self {
AttrValue::Boolean(v) => s.serialize_bool(*v),
AttrValue::Short(v) => s.serialize_i16(*v),
AttrValue::Long(v) => s.serialize_i32(*v),
AttrValue::Long64(v) => s.serialize_i64(*v),
AttrValue::UChar(v) => s.serialize_u8(*v),
AttrValue::UShort(v) => s.serialize_u16(*v),
AttrValue::ULong(v) => s.serialize_u32(*v),
AttrValue::ULong64(v) => s.serialize_u64(*v),
AttrValue::Float(v) => s.serialize_f32(*v),
AttrValue::Double(v) => s.serialize_f64(*v),
AttrValue::String(v) => match std::str::from_utf8(v) {
Ok(vs) => s.serialize_str(vs),
Err(_) => s.serialize_bytes(v)
},
AttrValue::State(v) => s.serialize_str(&v.to_string()),
AttrValue::Encoded(v) => v.serialize(s),
AttrValue::BooleanArray(v) => s.collect_seq(v),
AttrValue::ShortArray(v) => s.collect_seq(v),
AttrValue::LongArray(v) => s.collect_seq(v),
AttrValue::Long64Array(v) => s.collect_seq(v),
AttrValue::UCharArray(v) => s.collect_seq(v),
AttrValue::UShortArray(v) => s.collect_seq(v),
AttrValue::ULongArray(v) => s.collect_seq(v),
AttrValue::ULong64Array(v) => s.collect_seq(v),
AttrValue::FloatArray(v) => s.collect_seq(v),
AttrValue::DoubleArray(v) => s.collect_seq(v),
AttrValue::StringArray(v) => StringSeq(v).serialize(s),
AttrValue::StateArray(v) => s.collect_seq(v.iter().map(ToString::to_string)),
AttrValue::EncodedArray(v) => s.collect_seq(v),
}
}
}
impl Serialize for PropertyValue {
fn serialize<S: ser::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
match self {
PropertyValue::Empty => s.serialize_unit(),
PropertyValue::Boolean(v) => s.serialize_bool(*v),
PropertyValue::Short(v) => s.serialize_i16(*v),
PropertyValue::Long(v) => s.serialize_i32(*v),
PropertyValue::Long64(v) => s.serialize_i64(*v),
PropertyValue::UChar(v) => s.serialize_u8(*v),
PropertyValue::UShort(v) => s.serialize_u16(*v),
PropertyValue::ULong(v) => s.serialize_u32(*v),
PropertyValue::ULong64(v) => s.serialize_u64(*v),
PropertyValue::Float(v) => s.serialize_f32(*v),
PropertyValue::Double(v) => s.serialize_f64(*v),
PropertyValue::String(v) => match std::str::from_utf8(v) {
Ok(vs) => s.serialize_str(vs),
Err(_) => s.serialize_bytes(v)
},
PropertyValue::ShortArray(v) => s.collect_seq(v),
PropertyValue::LongArray(v) => s.collect_seq(v),
PropertyValue::Long64Array(v) => s.collect_seq(v),
PropertyValue::UShortArray(v) => s.collect_seq(v),
PropertyValue::ULongArray(v) => s.collect_seq(v),
PropertyValue::ULong64Array(v) => s.collect_seq(v),
PropertyValue::FloatArray(v) => s.collect_seq(v),
PropertyValue::DoubleArray(v) => s.collect_seq(v),
PropertyValue::StringArray(v) => StringSeq(v).serialize(s),
}
}
}