3.4 KiB
Example
Preserves schemas are written in a syntax that (ab)uses [Preserves text syntax][preserves::value::text] 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.
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
}>
}>
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);