use {
crate::{
lua::{Deserializer, LuaError, LuaTable, LuaValue, LuaVariant},
prelude::*,
},
glib::VariantDict,
serde::{
de,
ser::{self, SerializeMap, SerializeSeq},
Deserialize, Serialize,
},
std::fmt,
};
struct Visitor;
impl<'de> de::Visitor<'de> for Visitor {
type Value = LuaVariant<'static>;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("LuaVariant")
}
fn visit_unit<E: de::Error>(self) -> Result<Self::Value, E> {
Ok(().into())
}
fn visit_bool<E: de::Error>(self, v: bool) -> Result<Self::Value, E> {
Ok(v.into())
}
fn visit_i8<E: de::Error>(self, v: i8) -> Result<Self::Value, E> {
self.visit_i16(v.into())
}
fn visit_i16<E: de::Error>(self, v: i16) -> Result<Self::Value, E> {
Ok(v.into())
}
fn visit_i32<E: de::Error>(self, v: i32) -> Result<Self::Value, E> {
Ok(v.into())
}
fn visit_i64<E: de::Error>(self, v: i64) -> Result<Self::Value, E> {
Ok(v.into())
}
fn visit_u8<E: de::Error>(self, v: u8) -> Result<Self::Value, E> {
self.visit_u16(v.into())
}
fn visit_u16<E: de::Error>(self, v: u16) -> Result<Self::Value, E> {
Ok(v.into())
}
fn visit_u32<E: de::Error>(self, v: u32) -> Result<Self::Value, E> {
Ok(v.into())
}
fn visit_u64<E: de::Error>(self, v: u64) -> Result<Self::Value, E> {
Ok(v.into())
}
fn visit_f32<E: de::Error>(self, v: f32) -> Result<Self::Value, E> {
self.visit_f64(v.into())
}
fn visit_f64<E: de::Error>(self, v: f64) -> Result<Self::Value, E> {
Ok(v.into())
}
fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
Ok(v.into())
}
fn visit_seq<A: de::SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
let mut var: Vec<LuaVariant> = Vec::with_capacity(seq.size_hint().unwrap_or(0));
while let Some(v) = seq.next_element()? {
var.push(v);
}
Ok(LuaVariant::from_iter(var))
}
fn visit_map<A: de::MapAccess<'de>>(self, mut map: A) -> Result<Self::Value, A::Error> {
let dict = VariantDict::default();
while let Some((key, value)) = map.next_entry::<Cow<str>, _>()? {
dict.insert_value(&key, LuaVariant::as_variant(&value));
}
dict.end().try_into().map_err(LuaError::serde_error)
}
fn visit_none<E: de::Error>(self) -> Result<Self::Value, E> {
self.visit_unit()
}
fn visit_some<D: serde::Deserializer<'de>>(self, deserializer: D) -> Result<Self::Value, D::Error> {
deserializer.deserialize_any(self)
}
fn visit_enum<A: de::EnumAccess<'de>>(self, _data: A) -> Result<Self::Value, A::Error> {
Err(LuaError::Custom("unimplemented: wireplumber::lua::Visitor::visit_enum".into()).serde_error())
}
fn visit_bytes<E: de::Error>(self, v: &[u8]) -> Result<Self::Value, E> {
Ok(LuaVariant::with_bytes(v))
}
}
impl<'de, 'v> Deserialize<'de> for LuaVariant<'v> {
fn deserialize<D: de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
deserializer.deserialize_any(Visitor)
}
}
struct TableVisitor;
impl<'de> de::Visitor<'de> for TableVisitor {
type Value = LuaTable<'static>;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("LuaTable")
}
fn visit_map<A: de::MapAccess<'de>>(self, map: A) -> Result<Self::Value, A::Error> {
Visitor.visit_map(map).map(|v| unsafe { UnsafeFrom::unsafe_from(v) })
}
fn visit_seq<A: de::SeqAccess<'de>>(self, seq: A) -> Result<Self::Value, A::Error> {
Visitor.visit_seq(seq).map(|v| unsafe { UnsafeFrom::unsafe_from(v) })
}
}
impl<'de, 'v> Deserialize<'de> for LuaTable<'v> {
fn deserialize<D: de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
deserializer.deserialize_any(TableVisitor)
}
}
impl<'v> Serialize for LuaVariant<'v> {
fn serialize<S: ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
match self.lua_value() {
LuaValue::Nil => serializer.serialize_unit(),
LuaValue::Boolean(v) => serializer.serialize_bool(v),
LuaValue::Float(v) => serializer.serialize_f64(v),
LuaValue::Integer(v) => serializer.serialize_i64(v),
LuaValue::String(v) => match v.as_str() {
Ok(s) => serializer.serialize_str(s),
Err(_) => serializer.serialize_bytes(&v),
},
LuaValue::Table(t) => match t.is_array() {
Some(true) | None => {
let len = t.array_len();
let len = len
.try_into()
.map_err(|e| ser::Error::custom(format_args!("Lua array length {len} too large for usize: {e}")))?;
let mut ser = serializer.serialize_seq(Some(len))?;
for v in t.iter_array() {
match v {
Some(v) => ser.serialize_element(&v),
None => ser.serialize_element(&()),
}?
}
ser.end()
},
_ => {
let mut ser = serializer.serialize_map(Some(t.entry_len()))?;
for v in t.iter_dict_entries() {
ser.serialize_entry(v.key(), v.value())?;
}
ser.end()
},
},
}
}
}
impl<'v> Serialize for LuaTable<'v> {
fn serialize<S: ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.lua_variant().serialize(serializer)
}
}
impl<'de, 'v> de::IntoDeserializer<'de, LuaError> for LuaVariant<'v> {
type Deserializer = Deserializer<'v>;
fn into_deserializer(self) -> Self::Deserializer {
self.into()
}
}
impl<'a, 'de, 'v> de::IntoDeserializer<'de, LuaError> for &'a LuaVariant<'v> {
type Deserializer = Deserializer<'v>;
fn into_deserializer(self) -> Self::Deserializer {
self.clone().into()
}
}
impl<'de, 'v> de::IntoDeserializer<'de, LuaError> for LuaTable<'v> {
type Deserializer = Deserializer<'v>;
fn into_deserializer(self) -> Self::Deserializer {
self.into()
}
}
impl<'a, 'de, 'v> de::IntoDeserializer<'de, LuaError> for &'a LuaTable<'v> {
type Deserializer = Deserializer<'v>;
fn into_deserializer(self) -> Self::Deserializer {
self.clone().into()
}
}