Skip to content

Commit

Permalink
refactor: generate definitions and impls together
Browse files Browse the repository at this point in the history
  • Loading branch information
dnaka91 committed Sep 12, 2023
1 parent a624300 commit b32bcfd
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 148 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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))

### <!-- 4 -->🚜 Refactor

- Generate definitions and impls together ([e65b8cd](https://github.com/dnaka91/wazzup/commit/e65b8cdc8a3256eef36c4d5d0f42176506c9a90b))

### <!-- 7 -->⚙️ 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))
<!-- generated by git-cliff -->
48 changes: 46 additions & 2 deletions crates/stef-build/src/definition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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),
Expand Down Expand Up @@ -362,6 +380,13 @@ mod tests {
pub field2: Vec<u8>,
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);
Expand All @@ -387,6 +412,25 @@ mod tests {
Variant2(u32, u8),
Variant3 { field1: String, field2: Vec<bool> },
}
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);
Expand Down
138 changes: 3 additions & 135 deletions crates/stef-build/src/encode.rs
Original file line number Diff line number Diff line change
@@ -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: _,
Expand Down Expand Up @@ -98,7 +61,7 @@ fn compile_struct_fields(fields: &Fields<'_>) -> TokenStream {
}
}

fn compile_enum(
pub fn compile_enum(
Enum {
comment: _,
attributes: _,
Expand Down Expand Up @@ -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<bool> @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);
}
}
14 changes: 3 additions & 11 deletions crates/stef-build/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

use std::path::{Path, PathBuf};

use quote::quote;
use stef_parser::Schema;
use thiserror::Error;

Expand All @@ -30,16 +29,9 @@ pub fn compile(schemas: &[impl AsRef<Path>], _includes: &[impl AsRef<Path>]) ->
})?;

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(())
Expand Down

0 comments on commit b32bcfd

Please sign in to comment.