Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5fa28508 authored by Martin Geisler's avatar Martin Geisler
Browse files

PDL: add basic support for generating Rust code

This CL adds support for handling a simple PDL file which defines a
packet. The CL includes infrastructure for testing the generated code
against known-good output. This is sometimes called “snapshot
testing”. While there are crates for this, we currently don’t use any
to avoid pulling in new dependencies.

Bug: 228306440
Test: atest pdl_inline_tests
Change-Id: If33403444ba9e4ce9c45e15b65c1da03011aa5e9
parent 2c6d8a46
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line

package {
    // See: http://go/android-license-faq
    // A large-scale-change added 'default_applicable_licenses' to import
@@ -17,6 +16,11 @@ rust_defaults {
        "libserde_json",
        "libstructopt",
        "libcodespan_reporting",
        "libquote",
        "libsyn",
        "libproc_macro2",
        "libanyhow",
        "libtempfile",
    ],
    proc_macros: [
        "libpest_derive",
@@ -32,4 +36,8 @@ rust_test_host {
    name: "pdl_inline_tests",
    defaults: ["pdl_defaults"],
    test_suites: ["general-tests"],
    data: [
        "rustfmt",
        "rustfmt.toml",
    ],
}

tools/pdl/rustfmt

0 → 120000
+1 −0
Original line number Diff line number Diff line
../../../../../prebuilts/rust/linux-x86/stable/rustfmt
 No newline at end of file

tools/pdl/rustfmt.toml

0 → 120000
+1 −0
Original line number Diff line number Diff line
../../rustfmt.toml
 No newline at end of file
+640 −0

File added.

Preview size limit exceeded, changes collapsed.

+34 −1
Original line number Diff line number Diff line
@@ -4,11 +4,30 @@ use codespan_reporting::term::{self, termcolor};
use structopt::StructOpt;

mod ast;
mod generator;
mod lint;
mod parser;

use crate::lint::Lintable;

#[derive(Debug)]
enum OutputFormat {
    JSON,
    Rust,
}

impl std::str::FromStr for OutputFormat {
    type Err = String;

    fn from_str(input: &str) -> Result<Self, Self::Err> {
        match input.to_lowercase().as_str() {
            "json" => Ok(Self::JSON),
            "rust" => Ok(Self::Rust),
            _ => Err(format!("could not parse {:?}, valid option are 'json' and 'rust'.", input)),
        }
    }
}

#[derive(Debug, StructOpt)]
#[structopt(name = "pdl-parser", about = "Packet Description Language parser tool.")]
struct Opt {
@@ -16,6 +35,11 @@ struct Opt {
    #[structopt(short, long = "--version")]
    version: bool,

    /// Generate output in this format ("json" or "rust"). The output
    /// will be printed on stdout in both cases.
    #[structopt(short, long = "--output-format", name = "FORMAT", default_value = "JSON")]
    output_format: OutputFormat,

    /// Input file.
    #[structopt(name = "FILE")]
    input_file: String,
@@ -33,8 +57,17 @@ fn main() {
    match parser::parse_file(&mut sources, opt.input_file) {
        Ok(grammar) => {
            let _ = grammar.lint().print(&sources, termcolor::ColorChoice::Always);

            match opt.output_format {
                OutputFormat::JSON => {
                    println!("{}", serde_json::to_string_pretty(&grammar).unwrap())
                }
                OutputFormat::Rust => match generator::generate_rust(&sources, &grammar) {
                    Ok(code) => println!("{}", &code),
                    Err(err) => println!("failed to generate code: {}", err),
                },
            }
        }
        Err(err) => {
            let writer = termcolor::StandardStream::stderr(termcolor::ColorChoice::Always);
            let config = term::Config::default();
Loading