feat: with example code

Signed-off-by: kjuulh <contact@kjuulh.io>
This commit is contained in:
Kasper Juul Hermansen 2023-09-26 21:53:54 +02:00
parent 4cb1da85ca
commit 0a048257e2
Signed by: kjuulh
GPG Key ID: 9AA7BC13CE474394
6 changed files with 160 additions and 106 deletions

57
Cargo.lock generated
View File

@ -108,9 +108,9 @@ dependencies = [
[[package]] [[package]]
name = "async-task" name = "async-task"
version = "4.4.0" version = "4.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ecc7ab41815b3c653ccd2978ec3255c81349336702dfdf62ee6f7069b12a3aae" checksum = "b9441c6b2fe128a7c2bf680a44c34d0df31ce09e5b7e401fcca3faa483dbc921"
[[package]] [[package]]
name = "async-trait" name = "async-trait"
@ -125,9 +125,9 @@ dependencies = [
[[package]] [[package]]
name = "atomic-waker" name = "atomic-waker"
version = "1.1.1" version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1181e1e0d1fce796a03db1ae795d67167da795f9cf4a39c37589e85ef57f26d3" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
[[package]] [[package]]
name = "autocfg" name = "autocfg"
@ -212,17 +212,18 @@ dependencies = [
[[package]] [[package]]
name = "blocking" name = "blocking"
version = "1.3.1" version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77231a1c8f801696fc0123ec6150ce92cffb8e164a02afb9c8ddee0e9b65ad65" checksum = "94c4ef1f913d78636d78d538eec1f18de81e481f44b1be0a81060090530846e1"
dependencies = [ dependencies = [
"async-channel", "async-channel",
"async-lock", "async-lock",
"async-task", "async-task",
"atomic-waker", "fastrand 2.0.1",
"fastrand 1.9.0", "futures-io",
"futures-lite", "futures-lite",
"log", "piper",
"tracing",
] ]
[[package]] [[package]]
@ -357,9 +358,9 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
[[package]] [[package]]
name = "concurrent-queue" name = "concurrent-queue"
version = "2.2.0" version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62ec6771ecfa0762d24683ee5a32ad78487a3d3afdc0fb8cae19d2c5deb50b7c" checksum = "f057a694a54f12365049b0958a1685bb52d567f5593b355fbf685838e873d400"
dependencies = [ dependencies = [
"crossbeam-utils", "crossbeam-utils",
] ]
@ -764,9 +765,9 @@ dependencies = [
[[package]] [[package]]
name = "fastrand" name = "fastrand"
version = "2.0.0" version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
[[package]] [[package]]
name = "fixedbitset" name = "fixedbitset"
@ -837,13 +838,8 @@ version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce"
dependencies = [ dependencies = [
"fastrand 1.9.0",
"futures-core", "futures-core",
"futures-io",
"memchr",
"parking",
"pin-project-lite", "pin-project-lite",
"waker-fn",
] ]
[[package]] [[package]]
@ -1278,12 +1274,6 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
[[package]]
name = "parking"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e"
[[package]] [[package]]
name = "parking_lot" name = "parking_lot"
version = "0.12.1" version = "0.12.1"
@ -1344,6 +1334,17 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "piper"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4"
dependencies = [
"atomic-waker",
"fastrand 2.0.1",
"futures-io",
]
[[package]] [[package]]
name = "pkcs8" name = "pkcs8"
version = "0.7.6" version = "0.7.6"
@ -1924,7 +1925,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"fastrand 2.0.0", "fastrand 2.0.1",
"redox_syscall", "redox_syscall",
"rustix", "rustix",
"windows-sys", "windows-sys",
@ -2232,12 +2233,6 @@ version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "waker-fn"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca"
[[package]] [[package]]
name = "walkdir" name = "walkdir"
version = "2.4.0" version = "2.4.0"

View File

@ -53,45 +53,56 @@ impl Node {
} }
fn traverse(&self) -> genco::lang::rust::Tokens { fn traverse(&self) -> genco::lang::rust::Tokens {
for (_, node) in self.children.iter() { let mut child_tokens = Vec::new();
return node.traverse_indent(0); let mut nodes = self.children.iter().map(|(_, n)| n).collect::<Vec<_>>();
nodes.sort_by(|a, b| a.segment.cmp(&b.segment));
for node in nodes {
let tokens = node.traverse_indent(0);
child_tokens.push(tokens);
} }
self.traverse_indent(0) quote! {
pub mod $(&self.segment) {
$(for tokens in child_tokens join ($['\r']) => $tokens)
}
}
} }
fn traverse_indent(&self, indent: usize) -> genco::lang::rust::Tokens { fn traverse_indent(&self, indent: usize) -> genco::lang::rust::Tokens {
let padding = " ".repeat(indent * 4); let padding = " ".repeat(indent * 4);
println!("visited: {}", self.segment);
let mut message_tokens = Vec::new(); let mut message_tokens = Vec::new();
if let Some(file) = &self.file { if let Some(file) = &self.file {
if let Some(messages) = &self.messages { if let Some(messages) = &self.messages {
for message in messages.iter() { for message in messages.iter() {
println!("messages: {message}");
let tokens: genco::lang::rust::Tokens = quote! { let tokens: genco::lang::rust::Tokens = quote! {
$['\r']$(&padding)impl ::crunch::traits::Serializer for $(message) { impl ::crunch::traits::Serializer for $(message) {
$['\r']$(&padding) fn serialize(&self) -> Result<Vec<u8>, ::crunch::errors::SerializeError> { fn serialize(&self) -> Result<Vec<u8>, ::crunch::errors::SerializeError> {
$['\r']$(&padding) Ok(self.encode_to_vec()) Ok(self.encode_to_vec())
$['\r']$(&padding) } }
$['\r']$(&padding)} }
$['\r']$(&padding)impl ::crunch::traits::Deserializer for $(message) { impl ::crunch::traits::Deserializer for $(message) {
$['\r']$(&padding) fn deserialize(raw: Vec<u8>) -> Result<Self, ::crunch::errors::DeserializeError> fn deserialize(raw: Vec<u8>) -> Result<Self, ::crunch::errors::DeserializeError>
$['\r']$(&padding) where where
$['\r']$(&padding) Self: Sized, Self: Sized,
$['\r']$(&padding) { {
$['\r']$(&padding) let output = Self::decode(raw.as_slice()).map_err(|e| ::crunch::errors::DeserializeError::ProtoErr(e))?; let output = Self::decode(raw.as_slice()).map_err(|e| ::crunch::errors::DeserializeError::ProtoErr(e))?;
$['\r']$(&padding) Ok(output) Ok(output)
$['\r']$(&padding) } }
$['\r']$(&padding)} }
$['\r']$(&padding)
$['\r']$(&padding)impl crunch::traits::Event for $(message) { impl crunch::traits::Event for $(message) {
$['\r']$(&padding) fn event_info() -> ::crunch::traits::EventInfo { fn event_info() -> ::crunch::traits::EventInfo {
$['\r']$(&padding) ::crunch::traits::EventInfo { ::crunch::traits::EventInfo {
$['\r']$(&padding) domain: "my-domain", domain: "my-domain",
$['\r']$(&padding) entity_type: "my-entity-type", entity_type: "my-entity-type",
$['\r']$(&padding) event_name: "my-event-name", event_name: "my-event-name",
$['\r']$(&padding) } }
$['\r']$(&padding) } }
$['\r']$(&padding)} }
}; };
message_tokens.push(tokens); message_tokens.push(tokens);
@ -99,23 +110,25 @@ impl Node {
} }
quote! { quote! {
$['\r']$(&padding)pub mod $(&self.segment) { pub mod $(&self.segment) {
use prost::Message; use prost::Message;
$['\r']$(&padding)include!($(quoted(file))); include!($(quoted(file)));
$['\r']$(&padding)$(for tokens in message_tokens join ($['\r']) => $tokens) $(for tokens in message_tokens join ($['\r']) => $tokens)
$['\r']$(&padding)} }
} }
} else { } else {
let mut child_tokens = Vec::new(); let mut child_tokens = Vec::new();
for (_children, nodes) in &self.children { let mut nodes = self.children.iter().map(|(_, n)| n).collect::<Vec<_>>();
let tokens = nodes.traverse_indent(indent + 1); nodes.sort_by(|a, b| a.segment.cmp(&b.segment));
for node in nodes {
let tokens = node.traverse_indent(indent + 1);
child_tokens.push(tokens); child_tokens.push(tokens);
} }
quote! { quote! {
$['\r']$(&padding)pub mod $(&self.segment) { pub mod $(&self.segment) {
$(&padding)$(for tokens in child_tokens join ($['\r']) => $tokens) $(for tokens in child_tokens join ($['\r']) => $tokens)
$['\r']$(&padding)} }
} }
} }
} }
@ -236,15 +249,19 @@ impl Codegen {
let regex = Regex::new(r"pub struct (?P<eventName>[a-zA-Z0-9-_]+)") let regex = Regex::new(r"pub struct (?P<eventName>[a-zA-Z0-9-_]+)")
.expect("regex to be well formed"); .expect("regex to be well formed");
let mut output_paths = output_paths.to_vec();
output_paths.sort();
for generated_file in output_paths { for generated_file in output_paths {
if let Some(name) = generated_file.file_name() { if let Some(name) = generated_file.file_name() {
let file_name = name.to_str().unwrap(); let file_name = name.to_str().unwrap();
let file = tokio::fs::read_to_string(generated_file).await?; let file = tokio::fs::read_to_string(&generated_file).await?;
let messages = regex let mut messages = regex
.captures_iter(&file) .captures_iter(&file)
.map(|m| m.name("eventName").unwrap()) .map(|m| m.name("eventName").unwrap())
.map(|m| m.as_str().to_string()) .map(|m| m.as_str().to_string())
.collect(); .collect::<Vec<_>>();
messages.sort();
node.insert(file_name, messages); node.insert(file_name, messages);
} }

View File

@ -1,8 +1,9 @@
[service] [service]
service = "my-service" service = "basic-setup"
domain = "my-domain" domain = "examples"
codegen = ["rust"] codegen = ["rust"]
[[publish]] [[publish]]
schema-path = "schemas/crunch" schema-path = "schemas/crunch"
output-path = "src/gencrunch" output-path = "src/gencrunch"
entities = ["example"]

View File

@ -0,0 +1,7 @@
syntax = "proto3";
package examples.example;
message MyEvent {
string my_field = 1;
}

View File

@ -0,0 +1,6 @@
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct MyEvent {
#[prost(string, tag = "1")]
pub my_field: ::prost::alloc::string::String,
}

View File

@ -1,26 +1,54 @@
pub mod basic { pub mod root {
pub mod includes { pub mod basic {
pub mod my_include { pub mod includes {
use prost::Message; pub mod my_include {
include!("basic.includes.my_include.rs"); use prost::Message;
include!("basic.includes.my_include.rs");
impl ::crunch::traits::Serializer for MyInclude {
fn serialize(&self) -> Result<Vec<u8>, ::crunch::errors::SerializeError> {
Ok(self.encode_to_vec())
}
}
impl ::crunch::traits::Deserializer for MyInclude {
fn deserialize(raw: Vec<u8>) -> Result<Self, ::crunch::errors::DeserializeError>
where
Self: Sized,
{
let output = Self::decode(raw.as_slice()).map_err(|e| ::crunch::errors::DeserializeError::ProtoErr(e))?;
Ok(output)
}
}
impl ::crunch::traits::Serializer for MyInclude { impl crunch::traits::Event for MyInclude {
fn event_info() -> ::crunch::traits::EventInfo {
::crunch::traits::EventInfo {
domain: "my-domain",
entity_type: "my-entity-type",
event_name: "my-event-name",
}
}
}
}
}
pub mod my_event {
use prost::Message;
include!("basic.my_event.rs");
impl ::crunch::traits::Serializer for MyEvent {
fn serialize(&self) -> Result<Vec<u8>, ::crunch::errors::SerializeError> { fn serialize(&self) -> Result<Vec<u8>, ::crunch::errors::SerializeError> {
Ok(self.encode_to_vec()) Ok(self.encode_to_vec())
} }
} }
impl ::crunch::traits::Deserializer for MyInclude { impl ::crunch::traits::Deserializer for MyEvent {
fn deserialize(raw: Vec<u8>) -> Result<Self, ::crunch::errors::DeserializeError> fn deserialize(raw: Vec<u8>) -> Result<Self, ::crunch::errors::DeserializeError>
where where
Self: Sized, Self: Sized,
{ {
let output = Self::decode(raw.as_slice()) let output = Self::decode(raw.as_slice()).map_err(|e| ::crunch::errors::DeserializeError::ProtoErr(e))?;
.map_err(::crunch::errors::DeserializeError::ProtoErr)?;
Ok(output) Ok(output)
} }
} }
impl crunch::traits::Event for MyInclude { impl crunch::traits::Event for MyEvent {
fn event_info() -> ::crunch::traits::EventInfo { fn event_info() -> ::crunch::traits::EventInfo {
::crunch::traits::EventInfo { ::crunch::traits::EventInfo {
domain: "my-domain", domain: "my-domain",
@ -31,32 +59,32 @@ pub mod basic {
} }
} }
} }
pub mod my_event { pub mod examples {
use prost::Message; pub mod example {
include!("basic.my_event.rs"); use prost::Message;
include!("examples.example.rs");
impl ::crunch::traits::Serializer for MyEvent { impl ::crunch::traits::Serializer for MyEvent {
fn serialize(&self) -> Result<Vec<u8>, ::crunch::errors::SerializeError> { fn serialize(&self) -> Result<Vec<u8>, ::crunch::errors::SerializeError> {
Ok(self.encode_to_vec()) Ok(self.encode_to_vec())
}
} }
} impl ::crunch::traits::Deserializer for MyEvent {
impl ::crunch::traits::Deserializer for MyEvent { fn deserialize(raw: Vec<u8>) -> Result<Self, ::crunch::errors::DeserializeError>
fn deserialize(raw: Vec<u8>) -> Result<Self, ::crunch::errors::DeserializeError> where
where Self: Sized,
Self: Sized, {
{ let output = Self::decode(raw.as_slice()).map_err(|e| ::crunch::errors::DeserializeError::ProtoErr(e))?;
let output = Self::decode(raw.as_slice()) Ok(output)
.map_err(::crunch::errors::DeserializeError::ProtoErr)?; }
Ok(output)
} }
}
impl crunch::traits::Event for MyEvent { impl crunch::traits::Event for MyEvent {
fn event_info() -> ::crunch::traits::EventInfo { fn event_info() -> ::crunch::traits::EventInfo {
::crunch::traits::EventInfo { ::crunch::traits::EventInfo {
domain: "my-domain", domain: "my-domain",
entity_type: "my-entity-type", entity_type: "my-entity-type",
event_name: "my-event-name", event_name: "my-event-name",
}
} }
} }
} }