1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
// Copyright (c) Facebook, Inc. and its affiliates
// Copyright (c) Zefchain Labs, Inc.
// SPDX-License-Identifier: MIT OR Apache-2.0
//! This crate aims to compile the data formats extracted from Rust by [`serde-reflection`](https://crates.io/crates/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:
//!
//! * C++ 17
//! * Java 8
//! * Python 3 (requires numpy >= 1.20.1)
//! * Rust 2018
//! * Go >= 1.14
//! * C# (NetCoreApp >= 6.0)
//! * Swift 5.3
//! * OCaml
//! * Dart >= 3
//!
//! The following languages are partially supported and/or still considered under development:
//!
//! * TypeScript 4 (packaged and tested with Deno) [(follow-up issue)](https://github.com/zefchain/serde-reflection/issues/58)
//! * Solidity (tested with Revm) [(initial PR with discussion)](https://github.com/zefchain/serde-reflection/pull/61)
//!
//! ## 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](https://serde.rs/#data-formats).
//!
//! This crate provides easy-to-deploy runtime libraries for the following binary formats, in all supported languages:
//!
//! * [Bincode](https://docs.rs/bincode/1.3.1/bincode/) (default configuration only),
//! * [BCS](https://github.com/diem/bcs) (short for Binary Canonical Serialization, the main format used
//! in the [Diem blockchain](https://github.com/diem/diem)).
//!
//! ## Quick Start with Python and Bincode
//!
//! In the following example, we transfer a `Test` value from Rust to Python using [`bincode`](https://docs.rs/bincode/1.3.1/bincode/).
//! ```
//! use serde::{Deserialize, Serialize};
//! use serde_reflection::{Registry, Tracer, TracerConfig};
//! use std::io::Write;
//!
//! #[derive(Serialize, Deserialize)]
//! struct Test {
//! a: Vec<u64>,
//! b: (u32, u32),
//! }
//!
//! # fn main() -> Result<(), std::io::Error> {
//! // Obtain the Serde format of `Test`. (In practice, formats are more likely read from a file.)
//! let mut tracer = Tracer::new(TracerConfig::default());
//! tracer.trace_simple_type::<Test>().unwrap();
//! let registry = tracer.registry().unwrap();
//!
//! // Create Python class definitions.
//! let mut source = Vec::new();
//! let config = serde_generate::CodeGeneratorConfig::new("testing".to_string())
//! .with_encodings(vec![serde_generate::Encoding::Bincode]);
//! let generator = serde_generate::python3::CodeGenerator::new(&config);
//! generator.output(&mut source, ®istry)?;
//!
//! assert!(
//! String::from_utf8_lossy(&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").unwrap_or_default() + ":runtime/python")
//! .stdin(std::process::Stdio::piped())
//! .spawn()?;
//! child.stdin.as_mut().unwrap().write_all(&source)?;
//! let output = child.wait_with_output()?;
//! assert!(output.status.success());
//! # Ok(())
//! # }
//! ```
//!
//! ## 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 <<EOF
//! ---
//! 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-bin -- --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-bin -- --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-bin` then use `$HOME/.cargo/bin/serdegen`.
/// Dependency analysis and topological sort for Serde formats.
/// Utility function to generate indented text
/// Support for code-generation in C++
/// Support for code-generation in C#
/// Support for code-generation in Dart
/// Support for code-generation in Go
/// Support for code-generation in Java
/// Support for code-generation in OCaml
/// Support for code-generation in Python 3
/// Support for code-generation in Rust
/// Support for code-generation in solidity
/// Support for code-generation in Swift
/// Support for code-generation in TypeScript/JavaScript
/// Common logic for codegen.
/// Common configuration objects and traits used in public APIs.
pub use *;