From 9307d023652d343d927cb1f432eb0cf463f0e6a5 Mon Sep 17 00:00:00 2001 From: Cerber Ursi Date: Sat, 27 Nov 2021 19:09:06 +0700 Subject: [PATCH] Stub implementation --- .gitignore | 3 + Cargo.toml | 13 ++++ README.md | 27 ++++++- src/lib.rs | 209 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 251 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 src/lib.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6936990 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/target +**/*.rs.bk +Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..529e116 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "corona" +version = "0.1.0" +authors = ["k.bagrov "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +serde = "1.0" + +[dev-dependencies] +trybuild = "1.0" diff --git a/README.md b/README.md index 525ea11..0b61d6b 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,27 @@ # corona -Compiled Rust Object Notation - serializing to source code + +Makes Serde serialize your data to the Rust source code. + +### Why? + +This crate was inspired by the [Stack Overflow question](https://stackoverflow.com/questions/58359340/deserialize-file-using-serde-json-at-compile-time). In short, if you want to make some data in the human-readable format, such as JSON, to be deserialized at compile-time and build into the binary, as if it was written by hand, then this crate can possibly help you. + +### How to? + +This crate is intended to be used from the build script. It will serialize anything you provide to it to any path you provide (or to the arbitrary [`io::Write`](https://doc.rust-lang.org/stable/std/io/trait.Write.html) implementation, if you want to). Then, you'll [`include!`](https://doc.rust-lang.org/stable/std/macro.include.html) the generated file wherever you want to use it. + +### Is it really that simple? + +Well... not. There are several limitations. + +1. All the types used in the serialized struct must be in scope on the include site. Serde doesn't provide the qualified name (i.e. path) to the serializer, only the direct name. The probably easiest way is to use the serialized data as following: +```rust +let value = { + use ::path::to::Type1; + // ...and other types + include!("path/to/file.rs") +} +``` +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 diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..ca5090e --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,209 @@ +use serde::ser; +use std::io::Write; + +pub struct Corona(W); + +impl ser::Serializer for 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 + where + T: serde::Serialize { todo!() } + + fn serialize_unit(self) -> Result { todo!() } + + fn serialize_unit_struct(self, name: &'static str) -> Result { todo!() } + + fn serialize_unit_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + ) -> Result { todo!() } + + fn serialize_newtype_struct( + self, + name: &'static str, + value: &T, + ) -> Result + where + T: serde::Serialize { todo!() } + + fn serialize_newtype_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + value: &T, + ) -> Result + where + T: serde::Serialize { todo!() } + + fn serialize_seq(self, len: Option) -> Result { todo!() } + + fn serialize_tuple(self, len: usize) -> Result { todo!() } + + fn serialize_tuple_struct( + self, + name: &'static str, + len: usize, + ) -> Result { todo!() } + + fn serialize_tuple_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result { todo!() } + + fn serialize_map(self, len: Option) -> Result { todo!() } + + fn serialize_struct( + self, + name: &'static str, + len: usize, + ) -> Result { todo!() } + + fn serialize_struct_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result { todo!() } + + fn collect_str(self, value: &T) -> Result + where + T: std::fmt::Display { todo!() } + +} + +impl ser::SerializeSeq for 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!() } + +} +impl ser::SerializeTuple for 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!() } + +} +impl ser::SerializeTupleStruct for 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!() } + +} +impl ser::SerializeTupleVariant for 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!() } + +} +impl ser::SerializeMap for Corona { + type Ok = (); + type Error = CoronaError; + fn serialize_key(&mut self, key: &T) -> Result<(), Self::Error> + where + T: serde::Serialize { todo!() } + fn serialize_value(&mut self, value: &T) -> Result<(), Self::Error> + where + T: serde::Serialize { todo!() } + fn end(self) -> Result { todo!() } + +} +impl ser::SerializeStruct for 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!() } + +} +impl ser::SerializeStructVariant for 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!() } + +} + +#[derive(Debug)] +pub struct CoronaError(String); + +impl std::fmt::Display for CoronaError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { todo!() } +} + +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()) + } +} \ No newline at end of file