Skip to content

Commit

Permalink
Generate message formats using serde_reflection
Browse files Browse the repository at this point in the history
  • Loading branch information
ma2bd committed Aug 16, 2021
1 parent 4138266 commit 44ea348
Show file tree
Hide file tree
Showing 5 changed files with 350 additions and 11 deletions.
87 changes: 77 additions & 10 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions fastpay_core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,12 @@ serde = { version = "1.0.115", features = ["derive"] }
tokio = { version = "0.2.22", features = ["full"] }
ed25519 = { version = "1.0.1"}
ed25519-dalek = { version = "1.0.0-pre.3", features = ["batch"] }
serde-reflection = "0.3.2"
serde_yaml = "0.8.17"
structopt = "0.3.21"

[[bin]]
name = "generate-format"
path = "src/generate_format.rs"
test = false

5 changes: 4 additions & 1 deletion fastpay_core/src/base_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

use ed25519::signature::Signature as _;
use ed25519_dalek as dalek;
use ed25519_dalek::{Digest, Signer, Verifier};
use ed25519_dalek::{Signer, Verifier};

use rand::rngs::OsRng;
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -279,8 +279,11 @@ pub trait Digestible {
fn digest(&self) -> [u8; 32];
}

#[cfg(test)]
impl Digestible for [u8; 5] {
fn digest(self: &[u8; 5]) -> [u8; 32] {
use ed25519_dalek::Digest;

let mut h = dalek::Sha512::new();
let mut hash = [0u8; 64];
let mut digest = [0u8; 32];
Expand Down
63 changes: 63 additions & 0 deletions fastpay_core/src/generate_format.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright (c) Facebook Inc.
// SPDX-License-Identifier: Apache-2.0

use fastpay_core::{error, messages, serialize};

use serde_reflection::{Registry, Result, Samples, Tracer, TracerConfig};
use std::{fs::File, io::Write};
use structopt::{clap::arg_enum, StructOpt};

fn get_registry() -> Result<Registry> {
let mut tracer = Tracer::new(TracerConfig::default());
let samples = Samples::new();
// 1. Record samples for types with custom deserializers.
// tracer.trace_value(&mut samples, ...)?;

// 2. Trace the main entry point(s) + every enum separately.
tracer.trace_type::<messages::Address>(&samples)?;
tracer.trace_type::<error::FastPayError>(&samples)?;
tracer.trace_type::<serialize::SerializedMessage>(&samples)?;
tracer.registry()
}

arg_enum! {
#[derive(Debug, StructOpt, Clone, Copy)]
enum Action {
Print,
Test,
Record,
}
}

#[derive(Debug, StructOpt)]
#[structopt(
name = "FastPay format generator",
about = "Trace serde (de)serialization to generate format descriptions for FastPay types"
)]
struct Options {
#[structopt(possible_values = &Action::variants(), default_value = "Print", case_insensitive = true)]
action: Action,
}

const FILE_PATH: &str = "fastpay_core/tests/staged/fastpay.yaml";

fn main() {
let options = Options::from_args();
let registry = get_registry().unwrap();
match options.action {
Action::Print => {
let content = serde_yaml::to_string(&registry).unwrap();
println!("{}", content);
}
Action::Record => {
let content = serde_yaml::to_string(&registry).unwrap();
let mut f = File::create(FILE_PATH).unwrap();
writeln!(f, "{}", content).unwrap();
}
Action::Test => {
let f = File::open(FILE_PATH).unwrap();
let reference: serde_reflection::Registry = serde_yaml::from_reader(f).unwrap();
assert_eq!(registry, reference);
}
}
}
Loading

0 comments on commit 44ea348

Please sign in to comment.