Crate preserves_schema
source ·Expand description
cargo add preserves preserves-schema
This crate (preserves-schema
on crates.io) is an
implementation of Preserves Schema for Rust.
§What is Preserves Schema?
A Preserves schema connects Preserves Value
s to host-language data
structures. Each definition within a schema can be processed by a
compiler to produce
-
a simple host-language type definition;
-
a partial parsing function from
Value
s to instances of the produced type; and -
a total serialization function from instances of the type to
Value
s.
Every parsed Value
retains enough information to always be able to
be serialized again, and every instance of a host-language data
structure contains, by construction, enough information to be
successfully serialized.
§Example
Preserves schemas are written in a syntax that (ab)uses Preserves text syntax as a kind of S-expression. Schema source code looks like this:
version 1 .
Present = <Present @username string> .
Says = <Says @who string @what string> .
UserStatus = <Status @username string @status Status> .
Status = =here / <away @since TimeStamp> .
TimeStamp = string .
Conventionally, schema source code is stored in *.prs
files. In this example, the source code
above is placed in simpleChatProtocol.prs
.
The Rust code generator for schemas requires not source code, but instances of the Preserves metaschema. To compile schema source code to metaschema instances, use preserves-schemac:
yarn global add @preserves/schema
preserves-schemac .:simpleChatProtocol.prs > simpleChatProtocol.prb
Binary-syntax metaschema instances are conventionally stored in *.prb
files. If you have a
whole directory tree of *.prs
files, you can supply just “.
” without the “:
”-prefixed
fileglob part.1 See the preserves-schemac documentation.
§Generating Rust code from a schema
Generate Rust definitions corresponding to a metaschema instance with preserves-schema-rs.
The best way to use it is to integrate it into your build.rs
(see the
docs), but you can also use it as a standalone command-line tool.
The following command generates a directory ./rs/chat
containing rust sources for a module
that expects to be called chat
in Rust code:
preserves-schema-rs --output-dir rs/chat --prefix chat simpleChatProtocol.prb
Representative excerpts from one of the generated files, ./rs/chat/simple_chat_protocol.rs
:
pub struct Present {
pub username: std::string::String
}
pub struct Says {
pub who: std::string::String,
pub what: std::string::String
}
pub struct UserStatus {
pub username: std::string::String,
pub status: Status
}
pub enum Status {
Here,
Away {
since: std::boxed::Box<TimeStamp>
}
}
pub struct TimeStamp(pub std::string::String);
Converting the
simpleChatProtocol.prb
file to Preserves text syntax lets us read the metaschema instance corresponding to the source code:cat simpleChatProtocol.prb | preserves-tool convert
The result:
↩<bundle { [ simpleChatProtocol ]: <schema { definitions: { Present: <rec <lit Present> <tuple [ <named username <atom String>> ]>> Says: <rec <lit Says> <tuple [ <named who <atom String>> <named what <atom String>> ]>> Status: <or [ [ "here" <lit here> ] [ "away" <rec <lit away> <tuple [ <named since <ref [] TimeStamp>> ]>> ] ]> TimeStamp: <atom String> UserStatus: <rec <lit Status> <tuple [ <named username <atom String>> <named status <ref [] Status>> ]>> } embeddedType: #f version: 1 }> }>
Re-exports§
pub use support::Codec;
pub use support::Deserialize;
pub use support::ParseError;
Modules§
- Implementation of the Schema-to-Rust compiler; this is the core of the preserves-schema-rs program.
- Auto-generated Preserves Schema Metaschema types, parsers, and unparsers.
- The runtime support library for compiled Schemas.
- A library for emitting pretty-formatted structured source code.
Macros§
anglebrackets!(
a,
b,
…,
z)
⟶<
a,
b,
…,
z>
block!(
a,
b,
…,
z)
⟶{
a}
braces!(
a,
b,
…,
z)
⟶{
a,
b,
…,
z}
brackets!(
a,
b,
…,
z)
⟶[
a,
b,
…,
z]
commas!(
a,
b,
…,
z)
⟶ a,
b,
…,
zname!(
a,
b,
…,
z)
⟶ a::
b::
…::
zparens!(
a,
b,
…,
z)
⟶(
a,
b,
…,
z)
semiblock!(
a,
b,
…,
z)
⟶{
a;
b;
…;
z}
seq!(
a,
b,
…,
z)
⟶ ab…z