From d69f08cf0213ec852842b9c4979b52aecf251ce1 Mon Sep 17 00:00:00 2001 From: Cerber Ursi Date: Sat, 27 Nov 2021 19:09:08 +0700 Subject: [PATCH] Serializer implemented; using thiserror for CoronaError --- Cargo.toml | 6 +- README.md | 4 +- src/error.rs | 16 +- src/ser.rs | 411 ++++++++++++++++++++++++++++++++++++--------------- 4 files changed, 311 insertions(+), 126 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e71028c..0ff1556 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,4 +7,8 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -serde = "1.0" \ No newline at end of file +serde = "1.0" +thiserror = "1.0" + +[dev_dependencies] +batch_run = "1.0" \ No newline at end of file diff --git a/README.md b/README.md index 0b61d6b..f5459ec 100644 --- a/README.md +++ b/README.md @@ -24,4 +24,6 @@ let value = { ``` or the similar construction using [`lazy_static`](http://crates.io/crates/lazy_static). 2. As a consequence, all the types used by the serialized one must have distinct names (or they'll clash with each other). -3. Deserializer isn't implemented. This is intentional, since this crate isn't really intended for runtime usage. \ No newline at end of file +3. Deserializer isn't implemented. This is intentional, since this crate isn't really intended for runtime usage. +4. This serializer is intended to use with derived implementation. It may return bogus results when used with customized `Serialize`. +5. It is impossible to serialize the struct with private fields outside from the module it is defined in. In fact, to be able to serialize this type at all, you'll have to distribute two copies of your crate, one of which would only export the definition with derived `Serialize` to be used by this crate during the build-time of the second copy. (Isn't this a bit too complex?) \ No newline at end of file diff --git a/src/error.rs b/src/error.rs index 7e681c3..4681011 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,16 +1,16 @@ use serde::ser; +use thiserror::Error; -#[derive(Debug)] -pub struct CoronaError(String); - -impl std::fmt::Display for CoronaError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { todo!() } +#[derive(Error, Debug)] +pub enum CoronaError { + #[error("IO error while writing code: {0}")] + Io(#[from] std::io::Error), + #[error("Unknown error: {0}")] + Custom(String), } -impl std::error::Error for CoronaError {} - impl ser::Error for CoronaError { fn custom(msg:T)->Self where T: std::fmt::Display { - Self(msg.to_string()) + Self::Custom(msg.to_string()) } } \ No newline at end of file diff --git a/src/ser.rs b/src/ser.rs index 9e30842..53c1750 100644 --- a/src/ser.rs +++ b/src/ser.rs @@ -1,194 +1,373 @@ +use crate::error::CoronaError; use serde::ser; use std::io::Write; -use crate::error::CoronaError; -pub struct Corona(W); +type SerResult = Result<(), CoronaError>; -impl ser::Serializer for Corona { +pub struct Corona { + writer: W, + inside: bool, +} + +impl Corona { + fn start_sub(&mut self) -> &mut Self { + self.inside = true; + self + } + + fn serialize_item(&mut self, item: impl ser::Serialize) -> SerResult { + if self.inside { + write!(self.writer, ",")?; + } + self.inside = true; + item.serialize(self)?; + Ok(()) + } +} + +impl ser::Serializer for &mut Corona { type Ok = (); type Error = CoronaError; - type SerializeSeq = Corona; - type SerializeTuple = Corona; - type SerializeTupleStruct = Corona; - type SerializeTupleVariant = Corona; - type SerializeMap = Corona; - type SerializeStruct = Corona; - type SerializeStructVariant = Corona; - fn serialize_bool(self, v: bool) -> Result { todo!() } - - fn serialize_i8(self, v: i8) -> Result { todo!() } - - fn serialize_i16(self, v: i16) -> Result { todo!() } - - fn serialize_i32(self, v: i32) -> Result { todo!() } - - fn serialize_i64(self, v: i64) -> Result { todo!() } - - fn serialize_u8(self, v: u8) -> Result { todo!() } - - fn serialize_u16(self, v: u16) -> Result { todo!() } - - fn serialize_u32(self, v: u32) -> Result { todo!() } - - fn serialize_u64(self, v: u64) -> Result { todo!() } - - fn serialize_f32(self, v: f32) -> Result { todo!() } - - fn serialize_f64(self, v: f64) -> Result { todo!() } - - fn serialize_char(self, v: char) -> Result { todo!() } - - fn serialize_str(self, v: &str) -> Result { todo!() } - - fn serialize_bytes(self, v: &[u8]) -> Result { todo!() } - - fn serialize_none(self) -> Result { todo!() } - - fn serialize_some(self, value: &T) -> Result + type SerializeSeq = Self; + type SerializeTuple = Self; + type SerializeTupleStruct = Self; + type SerializeTupleVariant = Self; + type SerializeMap = Self; + type SerializeStruct = Self; + type SerializeStructVariant = Self; + + fn serialize_bool(self, v: bool) -> SerResult { + write!(self.writer, "{}", v.to_string())?; + Ok(()) + } + + fn serialize_i8(self, v: i8) -> SerResult { + write!(self.writer, "{}", v.to_string())?; + Ok(()) + } + + fn serialize_i16(self, v: i16) -> SerResult { + write!(self.writer, "{}", v.to_string())?; + Ok(()) + } + + fn serialize_i32(self, v: i32) -> SerResult { + write!(self.writer, "{}", v.to_string())?; + Ok(()) + } + + fn serialize_i64(self, v: i64) -> SerResult { + write!(self.writer, "{}", v.to_string())?; + Ok(()) + } + + fn serialize_i128(self, v: i128) -> SerResult { + write!(self.writer, "{}", v.to_string())?; + Ok(()) + } + + fn serialize_u8(self, v: u8) -> SerResult { + write!(self.writer, "{}", v.to_string())?; + Ok(()) + } + + fn serialize_u16(self, v: u16) -> SerResult { + write!(self.writer, "{}", v.to_string())?; + Ok(()) + } + + fn serialize_u32(self, v: u32) -> SerResult { + write!(self.writer, "{}", v.to_string())?; + Ok(()) + } + + fn serialize_u64(self, v: u64) -> SerResult { + write!(self.writer, "{}", v.to_string())?; + Ok(()) + } + + fn serialize_u128(self, v: u128) -> SerResult { + write!(self.writer, "{}", v.to_string())?; + Ok(()) + } + + fn serialize_f32(self, v: f32) -> SerResult { + write!(self.writer, "{}", v.to_string())?; + Ok(()) + } + + fn serialize_f64(self, v: f64) -> SerResult { + write!(self.writer, "{}", v.to_string())?; + Ok(()) + } + + fn serialize_char(self, v: char) -> SerResult { + write!(self.writer, "'{}'", v)?; + Ok(()) + } + + fn serialize_str(self, v: &str) -> SerResult { + write!(self.writer, "\"{}\"", v)?; + Ok(()) + } + + fn serialize_bytes(self, v: &[u8]) -> SerResult { + self.collect_seq(v)?; + Ok(()) + } + + fn serialize_none(self) -> SerResult { + write!(self.writer, "None")?; + Ok(()) + } + + fn serialize_some(self, value: &T) -> SerResult where - T: serde::Serialize { todo!() } - - fn serialize_unit(self) -> Result { todo!() } - - fn serialize_unit_struct(self, name: &'static str) -> Result { todo!() } - + T: serde::Serialize, + { + write!(self.writer, "Some(")?; + value.serialize(&mut *self)?; + write!(self.writer, ")")?; + Ok(()) + } + + fn serialize_unit(self) -> SerResult { + write!(self.writer, "()")?; + Ok(()) + } + + fn serialize_unit_struct(self, name: &'static str) -> SerResult { + write!(self.writer, "{}()", name)?; + Ok(()) + } + fn serialize_unit_variant( self, name: &'static str, - variant_index: u32, + _variant_index: u32, variant: &'static str, - ) -> Result { todo!() } - - fn serialize_newtype_struct( + ) -> SerResult { + write!(self.writer, "{}::{}()", name, variant)?; + Ok(()) + } + + fn serialize_newtype_struct(self, name: &'static str, value: &T) -> SerResult + where + T: serde::Serialize, + { + write!(self.writer, "{}(", name)?; + value.serialize(&mut *self)?; + write!(self.writer, ")")?; + Ok(()) + } + + fn serialize_newtype_variant( self, name: &'static str, - value: &T, - ) -> Result - where - T: serde::Serialize { todo!() } - - fn serialize_newtype_variant( - self, - name: &'static str, - variant_index: u32, + _variant_index: u32, variant: &'static str, value: &T, - ) -> Result + ) -> SerResult where - T: serde::Serialize { todo!() } - - fn serialize_seq(self, len: Option) -> Result { todo!() } - - fn serialize_tuple(self, len: usize) -> Result { todo!() } - + T: serde::Serialize, + { + write!(self.writer, "{}::{}(", name, variant)?; + value.serialize(&mut *self)?; + write!(self.writer, ")")?; + Ok(()) + } + + fn serialize_seq(self, _len: Option) -> Result { + write!(self.writer, "vec![")?; + Ok(self.start_sub()) + } + + fn serialize_tuple(self, _len: usize) -> Result { + write!(self.writer, "(")?; + Ok(self.start_sub()) + } + fn serialize_tuple_struct( self, name: &'static str, - len: usize, - ) -> Result { todo!() } - + _len: usize, + ) -> Result { + write!(self.writer, "{}(", name)?; + Ok(self.start_sub()) + } + fn serialize_tuple_variant( self, name: &'static str, - variant_index: u32, + _variant_index: u32, variant: &'static str, - len: usize, - ) -> Result { todo!() } - - fn serialize_map(self, len: Option) -> Result { todo!() } - + _len: usize, + ) -> Result { + write!(self.writer, "{}::{}", name, variant)?; + Ok(self.start_sub()) + } + + fn serialize_map(self, _len: Option) -> Result { + write!(self.writer, "vec![")?; + Ok(self.start_sub()) + } + fn serialize_struct( self, name: &'static str, - len: usize, - ) -> Result { todo!() } - + _len: usize, + ) -> Result { + write!(self.writer, "{} {{", name)?; + Ok(self.start_sub()) + } + fn serialize_struct_variant( self, name: &'static str, - variant_index: u32, + _variant_index: u32, variant: &'static str, - len: usize, - ) -> Result { todo!() } - - fn collect_str(self, value: &T) -> Result - where - T: std::fmt::Display { todo!() } - + _len: usize, + ) -> Result { + write!(self.writer, "{}::{} {{", name, variant)?; + Ok(self.start_sub()) + } } -impl ser::SerializeSeq for Corona { +impl ser::SerializeSeq for &mut Corona { type Ok = (); type Error = CoronaError; + fn serialize_element(&mut self, value: &T) -> Result<(), Self::Error> where - T: serde::Serialize { todo!() } - fn end(self) -> Result { todo!() } + T: serde::Serialize, + { + self.serialize_item(value) + } + fn end(self) -> SerResult { + write!(self.writer, "].into_iter().collect()")?; + Ok(()) + } } -impl ser::SerializeTuple for Corona { +impl ser::SerializeTuple for &mut Corona { type Ok = (); type Error = CoronaError; + fn serialize_element(&mut self, value: &T) -> Result<(), Self::Error> where - T: serde::Serialize { todo!() } - fn end(self) -> Result { todo!() } - + T: serde::Serialize, + { + self.serialize_item(value) + } + + fn end(self) -> SerResult { + write!(self.writer, ")")?; + Ok(()) + } } -impl ser::SerializeTupleStruct for Corona { +impl ser::SerializeTupleStruct for &mut Corona { type Ok = (); type Error = CoronaError; + fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> where - T: serde::Serialize { todo!() } - fn end(self) -> Result { todo!() } - + T: serde::Serialize, + { + self.serialize_item(value) + } + + fn end(self) -> SerResult { + write!(self.writer, ")")?; + Ok(()) + } } -impl ser::SerializeTupleVariant for Corona { +impl ser::SerializeTupleVariant for &mut Corona { type Ok = (); type Error = CoronaError; + fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> where - T: serde::Serialize { todo!() } - fn end(self) -> Result { todo!() } - + T: serde::Serialize, + { + self.serialize_item(value) + } + + fn end(self) -> SerResult { + write!(self.writer, ")")?; + Ok(()) + } } -impl ser::SerializeMap for Corona { +impl ser::SerializeMap for &mut Corona { type Ok = (); type Error = CoronaError; + fn serialize_key(&mut self, key: &T) -> Result<(), Self::Error> where - T: serde::Serialize { todo!() } + T: serde::Serialize, + { + // a little hack for code reuse + self.serialize_item("(")?; + key.serialize(&mut **self)?; + write!(self.writer, ",")?; + Ok(()) + } + fn serialize_value(&mut self, value: &T) -> Result<(), Self::Error> where - T: serde::Serialize { todo!() } - fn end(self) -> Result { todo!() } - + T: serde::Serialize, + { + value.serialize(&mut **self)?; + write!(self.writer, ")")?; + Ok(()) + } + + fn end(self) -> SerResult { + write!(self.writer, "].into_iter().collect()")?; + Ok(()) + } } -impl ser::SerializeStruct for Corona { +impl ser::SerializeStruct for &mut Corona { type Ok = (); type Error = CoronaError; + fn serialize_field( &mut self, key: &'static str, value: &T, ) -> Result<(), Self::Error> where - T: serde::Serialize { todo!() } - fn end(self) -> Result { todo!() } - + T: serde::Serialize, + { + self.serialize_item(format!("{}:", key))?; + value.serialize(&mut **self)?; + Ok(()) + } + + fn end(self) -> SerResult { + write!(self.writer, "}}")?; + Ok(()) + } } -impl ser::SerializeStructVariant for Corona { +impl ser::SerializeStructVariant for &mut Corona { type Ok = (); type Error = CoronaError; + fn serialize_field( &mut self, key: &'static str, value: &T, ) -> Result<(), Self::Error> where - T: serde::Serialize { todo!() } - fn end(self) -> Result { todo!() } - -} \ No newline at end of file + T: serde::Serialize, + { + self.serialize_item(format!("{}:", key))?; + value.serialize(&mut **self)?; + Ok(()) + } + + fn end(self) -> SerResult { + write!(self.writer, "}}")?; + Ok(()) + } +}