feat: add codegen lib

Signed-off-by: kjuulh <contact@kjuulh.io>
This commit is contained in:
Kasper Juul Hermansen 2023-09-24 14:02:01 +02:00
parent 09dfa6c2e3
commit 207a6f5c44
Signed by: kjuulh
GPG Key ID: 9AA7BC13CE474394
6 changed files with 118 additions and 66 deletions

11
Cargo.lock generated
View File

@ -545,6 +545,17 @@ dependencies = [
"tracing-subscriber",
]
[[package]]
name = "crunch-codegen"
version = "0.1.0"
dependencies = [
"anyhow",
"async-trait",
"crunch-traits",
"tokio",
"tracing",
]
[[package]]
name = "crunch-envelope"
version = "0.1.0"

View File

@ -23,5 +23,9 @@ nats = "0.24.0"
clap = {version = "4.4.4", features = ["derive"]}
toml_edit = {version = "0.20.0",features = ["serde"]}
serde = {version = "1.0.88", features = ["derive"]}
prost = {version = "0.12"}
prost-types = {version = "0.12"}
bytes = {version = "0.4"}
pretty_assertions = "1.4.0"

View File

@ -0,0 +1,14 @@
[package]
name = "crunch-codegen"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
crunch-traits.workspace = true
anyhow.workspace = true
tracing.workspace = true
tokio.workspace = true
async-trait.workspace = true

View File

@ -0,0 +1,14 @@
pub fn add(left: usize, right: usize) -> usize {
left + right
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let result = add(2, 2);
assert_eq!(result, 4);
}
}

View File

@ -10,12 +10,13 @@ name = "envelope_benchmark"
harness = false
[features]
default = ["json", "proto"]
default = ["proto", "capnp"]
json = ["dep:serde", "dep:serde_json", "dep:base64"]
proto = ["dep:prost", "dep:prost-types", "dep:bytes"]
capnp = ["dep:capnp"]
[dependencies]
capnp = "0.17.2"
capnp = { version = "0.17.2",optional = true}
thiserror.workspace = true
# Json
@ -24,9 +25,9 @@ serde_json = {version = "1.0.107",optional = true}
base64 = {version = "0.21.4",optional = true}
# Proto
prost = {version = "0.12", optional = true}
prost-types = {version = "0.12", optional = true}
bytes = {version = "0.4", optional = true}
prost = {workspace = true, optional = true}
prost-types = {workspace = true, optional = true}
bytes = {workspace = true, optional = true}
[build-dependencies]
capnpc = "0.17.2"

View File

@ -1,4 +1,5 @@
#[allow(dead_code)]
#[cfg(feature = "capnp")]
mod envelope_capnp;
#[cfg(feature = "json")]
@ -18,14 +19,79 @@ pub mod proto {
pub use crate::proto_envelope::*;
}
use capnp::message::{Builder, ReaderOptions};
use capnp::serialize;
#[cfg(feature = "capnp")]
pub mod capnp {
use capnp::message::{Builder, ReaderOptions};
use capnp::serialize;
use crate::{envelope_capnp, EnvelopeError, Metadata};
pub fn wrap<'a>(domain: &'a str, entity: &'a str, content: &'a [u8]) -> Vec<u8> {
let mut builder = Builder::new_default();
let mut envelope = builder.init_root::<envelope_capnp::envelope::Builder>();
envelope.set_content(content);
let mut metadata = envelope.init_metadata();
metadata.set_domain(domain);
metadata.set_entity(entity);
serialize::write_message_to_words(&builder)
}
pub fn unwrap(message: &[u8]) -> Result<(Vec<u8>, Metadata), EnvelopeError> {
let mut message = message;
let message_builder =
serialize::read_message_from_flat_slice(&mut message, ReaderOptions::new())
.map_err(EnvelopeError::CapnpError)?;
let envelope = message_builder
.get_root::<envelope_capnp::envelope::Reader>()
.map_err(EnvelopeError::CapnpError)?;
let content = envelope.get_content().map_err(EnvelopeError::CapnpError)?;
let metadata = envelope.get_metadata().map_err(EnvelopeError::CapnpError)?;
Ok((
content.to_vec(),
Metadata {
domain: metadata
.get_domain()
.map_err(EnvelopeError::CapnpError)?
.to_string(),
entity: metadata
.get_entity()
.map_err(EnvelopeError::CapnpError)?
.to_string(),
},
))
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_can_serialize() {
let domain = "some-domain";
let entity = "some-entity";
let message = b"some-content";
let out = wrap(domain, entity, message);
let original = unwrap(&out).expect("to be able to unwrap capnp message");
assert_eq!(domain, original.1.domain);
assert_eq!(entity, original.1.entity);
assert_eq!(message, original.0.as_slice());
}
}
}
use thiserror::Error;
#[derive(Error, Debug)]
pub enum EnvelopeError {
#[error("capnp failed to serialize or deserialize code")]
CapnpError(#[source] capnp::Error),
#[cfg(feature = "capnp")]
CapnpError(#[source] ::capnp::Error),
#[cfg(feature = "json")]
#[error("serde_json failed to serialize or deserialize code")]
JsonError(#[source] serde_json::Error),
@ -39,67 +105,9 @@ pub enum EnvelopeError {
MetadataError(),
}
pub fn wrap<'a>(domain: &'a str, entity: &'a str, content: &'a [u8]) -> Vec<u8> {
let mut builder = Builder::new_default();
let mut envelope = builder.init_root::<envelope_capnp::envelope::Builder>();
envelope.set_content(content);
let mut metadata = envelope.init_metadata();
metadata.set_domain(domain);
metadata.set_entity(entity);
serialize::write_message_to_words(&builder)
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct Metadata {
domain: String,
entity: String,
}
pub fn unwrap(message: &[u8]) -> Result<(Vec<u8>, Metadata), EnvelopeError> {
let mut message = message;
let message_builder =
serialize::read_message_from_flat_slice(&mut message, ReaderOptions::new())
.map_err(EnvelopeError::CapnpError)?;
let envelope = message_builder
.get_root::<envelope_capnp::envelope::Reader>()
.map_err(EnvelopeError::CapnpError)?;
let content = envelope.get_content().map_err(EnvelopeError::CapnpError)?;
let metadata = envelope.get_metadata().map_err(EnvelopeError::CapnpError)?;
Ok((
content.to_vec(),
Metadata {
domain: metadata
.get_domain()
.map_err(EnvelopeError::CapnpError)?
.to_string(),
entity: metadata
.get_entity()
.map_err(EnvelopeError::CapnpError)?
.to_string(),
},
))
}
#[cfg(test)]
mod test {
use crate::{unwrap, wrap};
#[test]
fn test_can_serialize() {
let domain = "some-domain";
let entity = "some-entity";
let message = b"some-content";
let out = wrap(domain, entity, message);
let original = unwrap(&out).expect("to be able to unwrap capnp message");
assert_eq!(domain, original.1.domain);
assert_eq!(entity, original.1.entity);
assert_eq!(message, original.0.as_slice());
}
}