use std::fmt::Formatter; use serde::de::value::SeqAccessDeserializer; use serde::de::{Error, SeqAccess, Unexpected, Visitor}; use serde::ser::SerializeSeq; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use crate::{JavaCodePoint, JavaStr, JavaString}; impl Serialize for JavaString { #[inline] fn serialize(&self, serializer: S) -> Result where S: Serializer, { match self.as_str() { Ok(str) => str.serialize(serializer), Err(_) => { let mut seq = serializer.serialize_seq(None)?; for ch in self.chars() { seq.serialize_element(&ch.as_u32())?; } seq.end() } } } } impl<'de> Deserialize<'de> for JavaString { #[inline] fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { deserializer.deserialize_any(JavaStringVisitor) } } struct JavaStringVisitor; impl<'de> Visitor<'de> for JavaStringVisitor { type Value = JavaString; fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result { formatter.write_str("a JavaString") } fn visit_str(self, v: &str) -> Result where E: Error, { Ok(JavaString::from(v)) } fn visit_string(self, v: String) -> Result where E: Error, { Ok(JavaString::from(v)) } fn visit_bytes(self, v: &[u8]) -> Result where E: Error, { match JavaStr::from_semi_utf8(v) { Ok(str) => Ok(str.to_owned()), Err(_) => Err(Error::invalid_value(Unexpected::Bytes(v), &self)), } } fn visit_byte_buf(self, v: Vec) -> Result where E: Error, { JavaString::from_semi_utf8(v) .map_err(|err| Error::invalid_value(Unexpected::Bytes(&err.into_bytes()), &self)) } fn visit_seq(self, seq: A) -> Result where A: SeqAccess<'de>, { let vec = Vec::::deserialize(SeqAccessDeserializer::new(seq))?; JavaString::from_semi_utf8(vec).map_err(|_| Error::invalid_value(Unexpected::Seq, &self)) } } impl Serialize for JavaStr { #[inline] fn serialize(&self, serializer: S) -> Result where S: Serializer, { match self.as_str() { Ok(str) => str.serialize(serializer), Err(_) => { let mut seq = serializer.serialize_seq(None)?; for ch in self.chars() { seq.serialize_element(&ch.as_u32())?; } seq.end() } } } } impl<'de: 'a, 'a> Deserialize<'de> for &'a JavaStr { #[inline] fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { deserializer.deserialize_any(JavaStrVisitor) } } struct JavaStrVisitor; impl<'de> Visitor<'de> for JavaStrVisitor { type Value = &'de JavaStr; fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result { formatter.write_str("a borrowed JavaStr") } fn visit_borrowed_str(self, v: &'de str) -> Result where E: Error, { Ok(JavaStr::from_str(v)) } fn visit_borrowed_bytes(self, v: &'de [u8]) -> Result where E: Error, { JavaStr::from_semi_utf8(v).map_err(|_| Error::invalid_value(Unexpected::Bytes(v), &self)) } } impl Serialize for JavaCodePoint { #[inline] fn serialize(&self, serializer: S) -> Result where S: Serializer, { match self.as_char() { Some(ch) => ch.serialize(serializer), None => self.as_u32().serialize(serializer), } } } impl<'de> Deserialize<'de> for JavaCodePoint { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { deserializer.deserialize_any(JavaCodePointVisitor) } } struct JavaCodePointVisitor; impl Visitor<'_> for JavaCodePointVisitor { type Value = JavaCodePoint; fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result { formatter.write_str("a character") } #[inline] fn visit_i8(self, v: i8) -> Result where E: Error, { self.visit_i32(v.into()) } #[inline] fn visit_i16(self, v: i16) -> Result where E: Error, { self.visit_i32(v.into()) } fn visit_i32(self, v: i32) -> Result where E: Error, { if v < 0 { Err(Error::invalid_value(Unexpected::Signed(v.into()), &self)) } else { self.visit_u32(v as u32) } } fn visit_i64(self, v: i64) -> Result where E: Error, { if v < 0 { Err(Error::invalid_value(Unexpected::Signed(v), &self)) } else { self.visit_u64(v as u64) } } #[inline] fn visit_u8(self, v: u8) -> Result where E: Error, { self.visit_u32(v.into()) } #[inline] fn visit_u16(self, v: u16) -> Result where E: Error, { self.visit_u32(v.into()) } fn visit_u32(self, v: u32) -> Result where E: Error, { JavaCodePoint::from_u32(v) .ok_or_else(|| Error::invalid_value(Unexpected::Unsigned(v.into()), &self)) } fn visit_u64(self, v: u64) -> Result where E: Error, { match u32::try_from(v) { Ok(v) => self.visit_u32(v), Err(_) => Err(Error::invalid_value(Unexpected::Unsigned(v), &self)), } } fn visit_char(self, v: char) -> Result where E: Error, { Ok(JavaCodePoint::from_char(v)) } fn visit_str(self, v: &str) -> Result where E: Error, { let mut iter = v.chars(); match (iter.next(), iter.next()) { (Some(c), None) => Ok(JavaCodePoint::from_char(c)), _ => Err(Error::invalid_value(Unexpected::Str(v), &self)), } } }