Rust build-dependency to generate code for encoding and decoding from MuON. Intended to be a good reference implementation for porting to other programming languages.
Make a file called "schemas/MyNotes.muon"
:::
# A list of books
book: list record
name: text
author: text
year: text
character: list record
name: text
location: text
cycles: number >= 0.0
byte: int >=0 <256
:::
In your build.rs
script:
fn main() {
muon_parser::file("./schemas/MyNotes.muon");
}
In src/endec.rs
:
include!(concat!(env!("OUT_DIR"), "/schemas/MyNotes.rs"));
Now the macro will expand to:
/// Automatically-generated from schema `schemas/MyNotes.muon`
pub struct MyNotes_Book_Character {
///
pub name: String,
///
pub location: String,
}
/// Automatically-generated from schema `schemas/MyNotes.muon`
pub struct MyNotes_Book {
///
pub name: String,
///
pub author: String,
///
pub year: i32,
///
pub character: Vec<MyNotes_Book_Character>,
}
/// Automatically-generated from schema `schemas/MyNotes.muon`
pub struct MyNotes {
/// A list of books
pub book: Vec<MyNotesBook>,
///
pub cycles: f32,
///
pub byte: u8,
}
impl Default for MyNotes {
fn default() -> Self {
MyNotes::new()
}
}
impl MyNotes {
/// Initialize to default values specified in schema (or if not present,
/// Rust's defined default)
pub fn new() -> Self {
// ...
}
/// Decode bytes into the struct.
pub const fn parse(slice: &[u8]) -> Result<Self> {
// ...
}
/// Read this format from a reader.
pub fn read<R: Read>(reader: R) -> Result<Self> {
// ...
}
/// Write this format into a writer.
pub fn write<W: Write>(&self, writer: W) -> Result<()> {
// ...
}
// ... (private functions)
}
Add a file to be read src/example.muon
:
book: Pale Fire
author: Vladimir Nabokov
year: 1962
character: John Shade
location: New Wye
character: Charles Kinbote
location: Zembla
book: The Curious Incident of the Dog in the Night-Time
author: Mark Haddon
year: 2003
character: Christopher Boone
location: Swindon
character: Siobhan
cycles: 1.5
byte: 42
Then in main.rs
,
mod muon_parser;
use muon_parser::MyNotes;
const MY_NOTES: MyNotes = MyNotes::parse(include!("src/example.muon"));
fn main() {
println!("{:?}", MY_NOTES);
}
It parses it at compile time! If you want to use runtime for compression or
other reasons, use read()
instead of parse()
. In this case the decoded data
is actually smaller, so it makes sense to use parse()
.