serde-generate

serde-generate on crates.io Documentation (latest release) License License

This crate aims to compile the data formats extracted from Rust by serde-reflection into type definitions and (de)serialization methods for other programming languages.

It can be used as a library or as a command-line tool (see serdegen below).

Supported Languages

The following programming languages are fully supported as target languages:

The following languages are partially supported and still considered under development:

Supported Encodings

Type definitions in a target language are meant to be used together with a runtime library that provides (de)serialization in a particular Serde encoding format.

This crate provides easy-to-deploy runtime libraries for the following binary formats, in all supported languages:

Quick Start with Python and Bincode

In the following example, we transfer a Test value from Rust to Python using bincode. ```rust use serde::{Deserialize, Serialize}; use serde_reflection::{Registry, Tracer, TracerConfig}; use std::io::Write;

[derive(Serialize, Deserialize)]

struct Test { a: Vec, b: (u32, u32), }

// Obtain the Serde format of Test. (In practice, formats are more likely read from a file.) let mut tracer = Tracer::new(TracerConfig::default()); tracer.tracesimpletype::().unwrap(); let registry = tracer.registry().unwrap();

// Create Python class definitions. let mut source = Vec::new(); let config = serdegenerate::CodeGeneratorConfig::new("testing".tostring()) .withencodings(vec![serdegenerate::Encoding::Bincode]); let generator = serde_generate::python3::CodeGenerator::new(&config); generator.output(&mut source, &registry)?;

assert!( String::fromutf8lossy(&source).contains( r#" @dataclass(frozen=True) class Test: a: typing.Sequence[st.uint64] b: typing.Tuple[st.uint32, st.uint32] "#));

// Append some test code to demonstrate Bincode deserialization // using the runtime in serde_generate/runtime/python/bincode. writeln!( source, r#" value = Test.bincode_deserialize(bytes({:?})) assert value == Test(a=[4, 6], b=(3, 5)) "#, bincode::serialize(&Test { a: vec![4, 6], b: (3, 5) }).unwrap(), )?;

// Execute the Python code. let mut child = std::process::Command::new("python3") .arg("-") .env("PYTHONPATH", std::env::var("PYTHONPATH").unwrapordefault() + ":runtime/python") .stdin(std::process::Stdio::piped()) .spawn()?; child.stdin.asmut().unwrap().writeall(&source)?; let output = child.waitwithoutput()?; assert!(output.status.success()); ```

Binary Tool

In addition to a Rust library, this crate provides a binary tool serdegen to process Serde formats saved on disk.

The tool serdegen assumes that a Rust value of type serde_reflection::Registry has been serialized into a YAML file. The recommended way to generate such a value is to use the library serde-reflection to introspect Rust definitions (see also the example above).

For a quick test, one may create a test file like this: ```bash

cat >test.yaml <

Foo: ENUM: 0: A: NEWTYPE: U64 1: B: UNIT EOF ```

Then, the following command will generate Python class definitions and write them into test.py: bash cargo run -p serde-generate -- --language python3 test.yaml > test.py

To create a python module test and install the bincode runtime in a directory $DEST, you may run: bash cargo run -p serde-generate -- --language python3 --with-runtimes serde bincode --module-name test --target-source-dir "$DEST" test.yaml

See the help message of the tool with --help for more options.

Note: Outside of this repository, you may install the tool with cargo install serde-generate then use $HOME/.cargo/bin/serdegen.

Contributing

See the CONTRIBUTING file for how to help out.

License

This project is available under the terms of either the Apache 2.0 license or the MIT license.