Skip to content

Commit

Permalink
Fix text format, add more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Kris030 committed Aug 8, 2023
1 parent 6ad5211 commit a495aa4
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 18 deletions.
54 changes: 39 additions & 15 deletions roblib/src/text_format/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,14 +149,37 @@ impl<'de, 'a, I: Iterator<Item = &'de str>> de::Deserializer<'de> for &'a mut De
where
V: de::Visitor<'de>,
{
visitor.visit_str(self.next()?)
self.deserialize_string(visitor)
}

fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
visitor.visit_string(self.next()?.to_string())
let spaces: usize = self.next()?.parse().map_err(|_| Error::Parse("usize"))?;

let mut next_str = || match self.next() {
Ok(v) => Ok(v),
Err(e) => {
if let Error::Empty | Error::MissingArgument = e {
Ok("")
} else {
Err(e)
}
}
};

if spaces == 0 {
return visitor.visit_str(next_str()?);
}

let mut s = String::from(next_str()?);
for _ in 0..spaces {
s.push(SEPARATOR);
s.push_str(next_str()?);
}

visitor.visit_string(s)
}

fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
Expand Down Expand Up @@ -209,18 +232,20 @@ impl<'de, 'a, I: Iterator<Item = &'de str>> de::Deserializer<'de> for &'a mut De
where
V: de::Visitor<'de>,
{
let len: u32 = self.next()?.parse().map_err(|_| Error::Parse("u32"))?;
visitor.visit_seq(Seq {
left: self.next()?.parse().map_err(|_| Error::Parse("usize"))?,
de: self,
left: len,
})
}

fn deserialize_tuple<V>(self, _: usize, visitor: V) -> Result<V::Value>
fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
self.deserialize_seq(visitor)
visitor.visit_seq(Seq {
de: self,
left: len,
})
}

fn deserialize_tuple_struct<V>(
Expand All @@ -234,18 +259,17 @@ impl<'de, 'a, I: Iterator<Item = &'de str>> de::Deserializer<'de> for &'a mut De
{
visitor.visit_seq(Seq {
de: self,
left: fields as u32,
left: fields,
})
}

fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
let len: u32 = self.next()?.parse().map_err(|_| Error::Parse("u32"))?;
visitor.visit_map(Seq {
left: self.next()?.parse().map_err(|_| Error::Parse("usize"))?,
de: self,
left: len,
})
}

Expand All @@ -260,7 +284,7 @@ impl<'de, 'a, I: Iterator<Item = &'de str>> de::Deserializer<'de> for &'a mut De
{
visitor.visit_seq(Seq {
de: self,
left: fields.len() as u32,
left: fields.len(),
})
}

Expand Down Expand Up @@ -293,7 +317,7 @@ impl<'de, 'a, I: Iterator<Item = &'de str>> de::Deserializer<'de> for &'a mut De

struct Seq<'de: 'a, 'a, I: Iterator<Item = &'de str>> {
de: &'a mut Deserializer<I>,
left: u32,
left: usize,
}

impl<'de, 'a, I: Iterator<Item = &'de str>> SeqAccess<'de> for Seq<'de, 'a, I> {
Expand All @@ -314,7 +338,7 @@ impl<'de, 'a, I: Iterator<Item = &'de str>> SeqAccess<'de> for Seq<'de, 'a, I> {
}

fn size_hint(&self) -> Option<usize> {
Some(self.left as usize)
Some(self.left)
}
}

Expand All @@ -341,7 +365,7 @@ impl<'de, 'a, I: Iterator<Item = &'de str>> MapAccess<'de> for Seq<'de, 'a, I> {
}

fn size_hint(&self) -> Option<usize> {
Some(self.left as usize)
Some(self.left)
}
}

Expand All @@ -358,8 +382,8 @@ impl<'de, 'a, I: Iterator<Item = &'de str>> EnumAccess<'de> for Enum<'de, 'a, I>
where
V: DeserializeSeed<'de>,
{
let var: u32 = self.de.next()?.parse().map_err(|_| Error::Parse("u32"))?;
let des: de::value::U32Deserializer<Error> = de::value::U32Deserializer::new(var);
let var = self.de.next()?.parse().map_err(|_| Error::Parse("usize"))?;
let des = de::value::UsizeDeserializer::<Error>::new(var);
let v = seed.deserialize(des)?;
Ok((v, self))
}
Expand Down
46 changes: 46 additions & 0 deletions roblib/src/text_format/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,52 @@ mod tests {
};
use rand::random;

#[test]
fn ser_matches_de_random_types() -> anyhow::Result<()> {
fn m<T: serde::Serialize + serde::de::DeserializeOwned>(v: &T) -> anyhow::Result<()> {
let txt1 = super::ser::to_string(v)?;
let res: T = match super::de::from_str(&txt1) {
Ok(v) => v,
Err(e) => {
println!("couldn't parse '{txt1}'");
Err(e)?
}
};
let txt2 = super::ser::to_string(&res)?;
if txt1 != txt2 {
println!("❌ {txt1} | {txt2}");
}

Ok(())
}

m(&String::from(""))?;
m(&String::from(" "))?;
m(&String::from(" asd asd "))?;
m(&String::from("asd asd asd asd 132"))?;

m(&(123u32, 42u8, 'a', true))?;
m(&[random::<isize>(), random(), random(), random()])?;
m(&vec![
Duration::from_secs_f64(random()),
Duration::from_secs_f64(random()),
Duration::from_secs_f64(random()),
Duration::from_secs_f64(random()),
])?;

#[derive(serde::Serialize, serde::Deserialize)]
struct Ads(char, f64);
m::<Vec<Result<String, Option<Ads>>>>(&vec![
Ok(" 0hello text format ".to_string()),
Ok("bye!".to_string()),
Err(None),
Err(None),
Err(Some(Ads(random(), random()))),
])?;

Ok(())
}

#[test]
fn ser_matches_de_event() -> anyhow::Result<()> {
for _ in 0..100 {
Expand Down
12 changes: 9 additions & 3 deletions roblib/src/text_format/ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ impl<W: fmt::Write> fmt::Write for Serializer<W> {
}

fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> fmt::Result {
self.put_separator = true;
self.formatting = true;
fmt::write(self, args)?;
self.formatting = false;
Expand Down Expand Up @@ -117,7 +116,14 @@ impl<W: fmt::Write> ser::Serializer for &mut Serializer<W> {
}

fn serialize_str(self, v: &str) -> Result<()> {
Ok(self.write_str(v)?)
let spaces = v.chars().filter(|c| *c == SEPARATOR).count();
write!(self, "{spaces}")?;

if !v.is_empty() {
self.write_str(v)?;
}

Ok(())
}

fn serialize_bytes(self, v: &[u8]) -> Result<()> {
Expand Down Expand Up @@ -180,7 +186,7 @@ impl<W: fmt::Write> ser::Serializer for &mut Serializer<W> {

fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
if let Some(len) = len {
write!(self, "{}", len as u32)?;
write!(self, "{}", len)?;
Ok(self)
} else {
Err(Error::UnsizedSeq)
Expand Down

1 comment on commit a495aa4

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Artifacts

View all

base roland
aarch64-unknown-linux-gnu Download Download
aarch64-unknown-linux-musl Download Download
armv7-unknown-linux-gnueabihf Download Download
armv7-unknown-linux-musleabihf Download Download
x86_64-pc-windows-msvc Download Download
x86_64-unknown-linux-gnu Download Download
x86_64-unknown-linux-musl Download Download

Please sign in to comment.