facet is an entire ecosystem of Rust crates built on top of reflection.
The core facet crates give types a SHAPE associated const with
details on the kind (struct, enum, tuple?), layout (size, alignment), fields,
doc comments, arbitrary attributes, along with
From there, facet-reflect allows reading from existing values, building new
values from scratch, and even mutating existing values in-place if they're plain
old data.
A rich (de)serialization ecosystem is built on top of these, for formats like JSON, TOML, YAML, MsgPack, Postcard, ASN1, XDR, CSV, XML, but also facet-native (ie. designed by the same authors and leveraging some capabilities that would be hard to get elsewhere) like styx (a human-oriented document language you'd use in place of YAML or TOML) and phon (a schema-aware binary format that comes in self-describing form and in compact form).
Inserting or fetching records from database is essentially (de)serialization again, so the facet ecosystem also includes adapters for sqlite and Postgres (via dibs, which does a little more than just data binding).
Want two programs to talk to each other? vox has you covered: an RPC system built on top of the Phon binary format, which purports to support forwards and backwards compatibility, although nobody's built the "semver checks" tooling for it yet so, PRs welcome.
Reflection has a cost: facet-json used to be 5-7x slower than serde-json. In comes weavy, an IR target that any crate can lower to, using their own intrinsics, for which they can provide native stencils. On platforms that support it, weavy uses a copy-patch technique to assemble native code for much faster (citation needed) execution still. Not an option on iPhone, and generally a memory safety liability.
For syntax highlighting, I (Amos) was a bit annoyed that arborium (a tree-sitter grammar distribution) required a C toolchain, so I made snark, a tree-sitter-compatible parser framework, which lowers to weavy, has JIT support, and will happily codegen an AST for you (into which it can parse your language) given a few extra annotations.
The https://facet.rs website has a lot of information about a lot of the ecosystem but it's unfortunately not super reliable as LLMs have been doing too much of the writing (on account on Amos being burned out). This is being slowly repaired. Bear with us.
The main facet crate re-exports symbols from:
- facet-core, which defines the main components:
- The [
Facet] trait and implementations for foreign types (mostlylibstd) - The [
Shape] struct along with various vtables and the whole [Def] tree - Type-erased pointer helpers like [
PtrUninit], [PtrConst], and [Opaque] - Autoderef specialization trick needed for
facet-macros
- The [
- facet-macros, which implements the [
Facet] derive attribute as a fast/light proc macro powered by unsynn
For struct manipulation and reflection, we have:
- facet-reflect, allows building values of arbitrary shapes in safe code, respecting invariants. It also allows peeking at existing values.
Internal crates include:
- facet-testhelpers a simple log logger and color-backtrace configured with the lightweight btparse backend
Various crates live under the https://github.com/facet-rs umbrella, and their repositories are kept somewhat-consistent through facet-dev.
Crates are in various states of progress, buyer beware!
In terms of data formats, we have:
- facet-json: JSON format support
- facet-toml: TOML format support
- facet-yaml: YAML format support
- facet-msgpack: MessagePack deserialization
- facet-asn1: ASN.1 format support
- facet-xdr: XDR format support
- facet-csv: CSV format support
- facet-xml: XML format support
Still adjacent to serialization/deserialization, we have:
- facet-urlencoded: URL-encoded form data deserialization
- figue: CLI arguments, config files, and environment variables (external crate)
As far as utilities go:
- facet-value: Memory-efficient dynamic value type, supporting JSON-like data plus bytes
- facet-pretty: Pretty-print Facet types
- facet-diff: Diffing capabilities for Facet types
- facet-assert: Pretty assertions for Facet types (no PartialEq required)
- facet-serialize: Generic iterative serialization facilities
- facet-deserialize: Generic iterative deserialization facilities
And the less developed:
- facet-inspect: Utilities to inspect the content of a Facet object
These crates previously lived in separate repositories and now live in this monorepo:
- facet-xml: XML/DOM ecosystem (includes facet-xml, facet-dom, facet-svg, facet-atom, facet-xml-node, facet-singularize)
- facet-axum: Axum web framework integration
Some crates are developed completely independently from the facet org:
- facet-v8 provides an experimental Facet/v8 integration
- facet-openapi (experimental) Generates OpenAPI definitions from types that implement Facet
- facet_generate reflects Facet types into Java, Swift and TypeScript
- multi-array-list provides an experimental
MultiArrayListtype
Thanks to all individual sponsors:
...without whom this work could not exist.
The facet logo was drawn by Misiasart.
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.