#reflection #facet #deserialize #introspection

no-std facet

Re-exports the Facet trait and derive macros, along with Shape and all related types

42 releases (7 breaking)

Uses new Rust 2024

new 0.18.4 May 2, 2025
0.17.0 Apr 26, 2025

#29 in Development tools

Download history 1015/week @ 2025-04-06 1382/week @ 2025-04-13 1525/week @ 2025-04-20 819/week @ 2025-04-27

4,741 downloads per month
Used in 4 crates (3 directly)

MIT/Apache

480KB
9K SLoC

Facet logo - a reflection library for Rust

Coverage Status free of syn crates.io documentation MIT/Apache-2.0 licensed

Logo by Misiasart

Thanks to all individual and corporate sponsors, without whom this work could not exist:

Ko-fi GitHub Sponsors Patreon Zed Depot

facet provides reflection for Rust: it gives types a SHAPE associated const with details on the layout, fields, doc comments, attributes, etc.

It can be used for many things, from (de)serialization to pretty-printing, rich debuggers, CLI parsing, reflection in templating engines, code generation, etc.

See https://facet.rs for details.

Known issues and limitations

We have the occasional soundness issue, see the soundness tag. Those are prioritized and fixed as soon as possible.

Format crates like facet-json are still very much incomplete, and will probably always be slower than the serde-* equivalent. Reflection has advantages in terms of flexibility, ergonomics and compile time but has a runtime cost compared to "monomorphize all the things".

(Note: with codegen, one could get the best of both worlds. To be researched more)

Some format crates (like facet-toml) first deserialize to a DOM, and then to partial structs — this is not as efficient as it could be, but it's a good first step.

Rust 1.86.0 has a compile error if you just import Facet but don't use it, see https://github.com/facet-rs/facet/issues/75. This is fixed in nightly and will no longer be a problem with the next major Rust version.

type_eq is not const, thus preventing many useful things in const fn, see https://github.com/facet-rs/facet/issues/98. Language changes are needed to address that.

The design of arbitrary attributes is still in flux, see:

There isn't a comparison between facet-reflect and bevy-reflect available right now— this is by design. We're letting facet develop on its own for a while; we'll make a detailed comparison once things have settled.

There are more issues and limitations of course, but this should get you started.

Ecosystem

The core crates, facet-trait, facet-types etc. are no_std-friendly.

The main facet crate re-exports symbols from:

  • facet-core, which defines the main components:
    • The Facet trait and implementations for foreign types (mostly libstd)
    • 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-derive
  • facet-derive, which implements the Facet derive attribute as a fast/light proc macro powered by unsynn

For struct manipulation and reflection, the following is available:

  • facet-reflect, allows building values of arbitrary shapes in safe code, respecting invariants. It also allows peeking at existing values.
  • facet-pretty is able to pretty-print Facet types.

facet supports deserialization from multiple data formats through dedicated crates:

Internal crates include:

  • facet-codegen is internal and generates some of the code of facet-core
  • facet-testhelpers a simpler log logger and color-backtrace configured with the lightweight btparse backend

License

Licensed under either of:

at your option.

Dependencies

~450–620KB
~11K SLoC