From b32bcfd8630bc445421ce32b784de6601659aade Mon Sep 17 00:00:00 2001 From: Dominik Nakamura Date: Tue, 12 Sep 2023 21:39:26 +0900 Subject: [PATCH] refactor: generate definitions and impls together --- CHANGELOG.md | 5 + crates/stef-build/src/definition.rs | 48 +++++++++- crates/stef-build/src/encode.rs | 138 +--------------------------- crates/stef-build/src/lib.rs | 14 +-- 4 files changed, 57 insertions(+), 148 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20604f0..c199fb7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,8 +17,13 @@ All notable changes to this project will be documented in this file. - Generate more stylish changelog ([5319fb3](https://github.com/dnaka91/wazzup/commit/5319fb3417a830042e7bc220fe283046923da349)) - Add changelog ([5b2a15c](https://github.com/dnaka91/wazzup/commit/5b2a15cad70e53c6c39a93c395fbe8f80382ae56)) +### 🚜 Refactor + +- Generate definitions and impls together ([e65b8cd](https://github.com/dnaka91/wazzup/commit/e65b8cdc8a3256eef36c4d5d0f42176506c9a90b)) + ### ⚙️ Miscellaneous Tasks - Initial commit ([5eb2f2b](https://github.com/dnaka91/wazzup/commit/5eb2f2b9687146363974ea645de22a8441e890a1)) - Update checkout action to v4 ([4d753d8](https://github.com/dnaka91/wazzup/commit/4d753d8b30ef3ee7d7e463fb2e7f594aee86d8e7)) +- Minor code cleanup of unused code ([a624300](https://github.com/dnaka91/wazzup/commit/a6243007663ddcf1d4a9da09c9b4b6514dab0db6)) diff --git a/crates/stef-build/src/definition.rs b/crates/stef-build/src/definition.rs index 4fddcbb..9001a3a 100644 --- a/crates/stef-build/src/definition.rs +++ b/crates/stef-build/src/definition.rs @@ -5,6 +5,8 @@ use stef_parser::{ Module, NamedField, Schema, Struct, TypeAlias, UnnamedField, Variant, }; +use super::encode; + pub(crate) fn compile_schema(Schema { definitions }: &Schema<'_>) -> TokenStream { let definitions = definitions.iter().map(compile_definition); @@ -14,8 +16,24 @@ pub(crate) fn compile_schema(Schema { definitions }: &Schema<'_>) -> TokenStream fn compile_definition(definition: &Definition<'_>) -> TokenStream { let definition = match definition { Definition::Module(m) => compile_module(m), - Definition::Struct(s) => compile_struct(s), - Definition::Enum(e) => compile_enum(e), + Definition::Struct(s) => { + let def = compile_struct(s); + let encode = encode::compile_struct(s); + + quote! { + #def + #encode + } + } + Definition::Enum(e) => { + let def = compile_enum(e); + let encode = encode::compile_enum(e); + + quote! { + #def + #encode + } + } Definition::TypeAlias(a) => compile_alias(a), Definition::Const(c) => compile_const(c), Definition::Import(i) => compile_import(i), @@ -362,6 +380,13 @@ mod tests { pub field2: Vec, pub field3: (bool, [i16; 4]), } + impl ::stef::Encode for Sample { + fn encode(&self, w: &mut impl ::stef::BufMut) { + ::stef::write_field(w, 1, |w| { ::stef::encode_u32(w, self.field1) }); + ::stef::write_field(w, 2, |w| { ::stef::encode_bytes(w, &self.field2) }); + ::stef::write_field(w, 3, |w| { ::stef::write_tuple2(w, &self.field3) }); + } + } "#}; parse(input, expect); @@ -387,6 +412,25 @@ mod tests { Variant2(u32, u8), Variant3 { field1: String, field2: Vec }, } + impl ::stef::Encode for Sample { + fn encode(&self, w: &mut impl ::stef::BufMut) { + match self { + Self::Variant1 => { + ::stef::write_id(w, 1); + } + Self::Variant2(n0, n1) => { + ::stef::write_id(w, 2); + ::stef::write_field(w, 1, |w| { ::stef::encode_u32(w, n0) }); + ::stef::write_field(w, 2, |w| { ::stef::encode_u8(w, n1) }); + } + Self::Variant3 { field1, field2 } => { + ::stef::write_id(w, 3); + ::stef::write_field(w, 1, |w| { ::stef::encode_string(w, &field1) }); + ::stef::write_field(w, 2, |w| { ::stef::encode_vec(w, &field2) }); + } + } + } + } "#}; parse(input, expect); diff --git a/crates/stef-build/src/encode.rs b/crates/stef-build/src/encode.rs index 813abbe..3bd973f 100644 --- a/crates/stef-build/src/encode.rs +++ b/crates/stef-build/src/encode.rs @@ -1,45 +1,8 @@ use proc_macro2::{Ident, Span, TokenStream}; use quote::{quote, ToTokens}; -use stef_parser::{ - DataType, Definition, Enum, Fields, Module, NamedField, Schema, Struct, - UnnamedField, Variant, -}; +use stef_parser::{DataType, Enum, Fields, NamedField, Struct, UnnamedField, Variant}; -pub(crate) fn compile_schema(Schema { definitions }: &Schema<'_>) -> TokenStream { - let definintions = definitions.iter().map(compile_definition); - - quote! { #(#definintions)* } -} - -fn compile_definition(definition: &Definition<'_>) -> TokenStream { - let definition = match definition { - Definition::Module(m) => compile_module(m), - Definition::Struct(s) => compile_struct(s), - Definition::Enum(e) => compile_enum(e), - Definition::TypeAlias(_) | Definition::Const(_) | Definition::Import(_) => quote! {}, - }; - - quote! { #definition } -} - -fn compile_module( - Module { - comment: _, - name, - definitions, - }: &Module<'_>, -) -> TokenStream { - let name = Ident::new(name, Span::call_site()); - let definitions = definitions.iter().map(compile_definition); - - quote! { - pub mod #name { - #(#definitions)* - } - } -} - -fn compile_struct( +pub fn compile_struct( Struct { comment: _, attributes: _, @@ -98,7 +61,7 @@ fn compile_struct_fields(fields: &Fields<'_>) -> TokenStream { } } -fn compile_enum( +pub fn compile_enum( Enum { comment: _, attributes: _, @@ -246,98 +209,3 @@ fn compile_data_type(ty: &DataType<'_>, name: TokenStream) -> TokenStream { } } } - -#[cfg(test)] -mod tests { - use indoc::indoc; - use pretty_assertions::assert_eq; - - use super::*; - - fn parse(input: &str, expect: &str) { - let parsed = Schema::parse(input).unwrap(); - println!("==========\n{parsed}"); - - let compiled = compile_schema(&parsed); - println!("----------\n{compiled}"); - - let pretty = prettyplease::unparse(&syn::parse2(compiled.clone()).unwrap()); - println!("----------\n{pretty}=========="); - - assert_eq!(expect, pretty); - } - - #[test] - fn basic_module() { - let input = indoc! {r#" - /// Hello world! - mod sample {} - "#}; - let expect = indoc! {r#" - pub mod sample {} - "#}; - - parse(input, expect); - } - - #[test] - fn basic_struct() { - let input = indoc! {r#" - /// Hello world! - struct Sample { - field1: u32 @1, - field2: bytes @2, - field3: (bool, [i16; 4]) @3, - } - "#}; - let expect = indoc! {r#" - impl ::stef::Encode for Sample { - fn encode(&self, w: &mut impl ::stef::BufMut) { - ::stef::write_field(w, 1, |w| { ::stef::encode_u32(w, self.field1) }); - ::stef::write_field(w, 2, |w| { ::stef::encode_bytes(w, &self.field2) }); - ::stef::write_field(w, 3, |w| { ::stef::write_tuple2(w, &self.field3) }); - } - } - "#}; - - parse(input, expect); - } - - #[test] - fn basic_enum() { - let input = indoc! {r#" - /// Hello world! - enum Sample { - Variant1 @1, - Variant2(u32 @1, u8 @2) @2, - Variant3 { - field1: string @1, - field2: vec @2, - } @3, - } - "#}; - let expect = indoc! {r#" - impl ::stef::Encode for Sample { - fn encode(&self, w: &mut impl ::stef::BufMut) { - match self { - Self::Variant1 => { - ::stef::write_id(w, 1); - } - Self::Variant2(n0, n1) => { - ::stef::write_id(w, 2); - ::stef::write_field(w, 1, |w| { ::stef::encode_u32(w, n0) }); - ::stef::write_field(w, 2, |w| { ::stef::encode_u8(w, n1) }); - } - Self::Variant3 { field1, field2 } => { - ::stef::write_id(w, 3); - ::stef::write_field(w, 1, |w| { ::stef::encode_string(w, &field1) }); - ::stef::write_field(w, 2, |w| { ::stef::encode_vec(w, &field2) }); - } - } - } - } - "#}; - - parse(input, expect); - } -} diff --git a/crates/stef-build/src/lib.rs b/crates/stef-build/src/lib.rs index 556bb47..6234067 100644 --- a/crates/stef-build/src/lib.rs +++ b/crates/stef-build/src/lib.rs @@ -3,7 +3,6 @@ use std::path::{Path, PathBuf}; -use quote::quote; use stef_parser::Schema; use thiserror::Error; @@ -30,16 +29,9 @@ pub fn compile(schemas: &[impl AsRef], _includes: &[impl AsRef]) -> })?; let schema = Schema::parse(&input).unwrap(); - let definition = definition::compile_schema(&schema); - let encode = encode::compile_schema(&schema); - - println!( - "{}", - quote! { - #definition - #encode - } - ); + let code = definition::compile_schema(&schema); + + println!("{code}"); } Ok(())