4 releases
0.2.0 | Apr 22, 2024 |
---|---|
0.1.2 | Apr 21, 2024 |
0.1.1 | Apr 21, 2024 |
0.1.0 | Apr 21, 2024 |
#733 in Procedural macros
26KB
523 lines
bare_proc
bare_proc
is a proc-macro that implements a parser-generator for the
BARE message format.
It relies on serde
using
serde_bare
to implement serialization.
Usage
Define you BARE schema in a .bare file:
type User struct {
name: str
key: data[128]
id: uint
}
Then in a corresponding Rust file:
bare_schema!("schema.bare");
which will expand roughly the following:
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug)]
struct User {
name: String,
key: Vec<u8>,
id: u64,
}
License
bare_proc
is licensed under MIT.
lib.rs
:
bare_proc
provides a simple procedural macro that generates Rust types from BARE schema files.
Generated types implicitly implement serde::Serialize
and serde::Deserialize
, as serde_bare
is used to handle encoding and decoding. Please see
serde_bare's documentation for information on how
the Rust data model maps to the BARE data model.
To use this macro, define a BARE schema file and populate it with type declarations.
For example:
// schema.bare
type PublicKey data[128]
type Time str # ISO 8601
type Department enum {
ACCOUNTING
ADMINISTRATION
CUSTOMER_SERVICE
DEVELOPMENT
JSMITH = 99
}
type Address list<str>[4] # street, city, state, country
type Customer struct {
name: str
email: str
address: Address
orders: list<struct {
orderId: i64
quantity: i32
}>
metadata: map<str><data>
}
type Employee struct {
name: str
email: str
address: Address
department: Department
hireDate: Time
publicKey: optional<PublicKey>
metadata: map<str><data>
}
type TerminatedEmployee void
type Person union {Customer | Employee | TerminatedEmployee}
Then, within a Rust source file:
use bare_proc::bare_schema;
bare_proc!("schema.bare");
let noah = Employee {
name: "Noah",
email: "noah@packetlost.dev",
address: ["", "", "", ""],
department: Department::ACCOUNTING,
hireDate: Vec::<u8>::new(),
publicKey: None,
metadata: HashMap::new(),
};
BARE => Rust Data Mapping
In most areas, the BARE data model maps cleanly to a Rust representation. Unless otherwise
specified, the most obvious Rust data type is generated from a given BARE type. For example,
a BARE option<type>
is mapped to Rust's Option<type>
, BARE unions and enums are mapped to
Rust enum
s. See below for opinions that this crate has around data types that do not map
as cleanly or require additional explanation.
Maps
BARE maps are interpreted as HashMap<K, V>
in Rust. As of now, this is not configurable, but
may be in the future.
Variable Length Integers
The variable uint
and int
types are mapped to serde_bare::UInt
and serde_bare::Int
respectively. These types wrap u64
and i64
(the largest possible sized values stored in BARE
variable length integers).
Arrays that have 32 or less elements are mapped directly as Rust arrays, while BARE arrays with
more than 32 elements are converted into Vec<T>
.
Dependencies
~2.2–3MB
~61K SLoC