Reflect types annotated with #[derive(Facet)]
into Java, Swift, and TypeScript.
cargo add facet facet_generate
use facet::Facet; #[derive(Facet)] #[repr(C)] enum HttpResult { Ok(HttpResponse), Err(HttpError), } #[derive(Facet)] struct HttpResponse { status: u16, headers: Vec<HttpHeader>, #[facet(bytes)] body: Vec<u8>, } #[derive(Facet)] struct HttpHeader { name: String, value: String, } #[derive(Facet)] #[repr(C)] enum HttpError { #[facet(skip)] Http { status: u16, message: String, body: Option<Vec<u8>>, }, #[facet(skip)] Json(String), Url(String), Io(String), Timeout, } let registry = Registry::new().add_type::<HttpResult>().build(); insta::assert_yaml_snapshot!(registry, @r" ? namespace: ROOT name: HttpError : ENUM: 0: Url: NEWTYPE: STR 1: Io: NEWTYPE: STR 2: Timeout: UNIT ? namespace: ROOT name: HttpHeader : STRUCT: - name: STR - value: STR ? namespace: ROOT name: HttpResponse : STRUCT: - status: U16 - headers: SEQ: TYPENAME: namespace: ROOT name: HttpHeader - body: BYTES ? namespace: ROOT name: HttpResult : ENUM: 0: Ok: NEWTYPE: TYPENAME: namespace: ROOT name: HttpResponse 1: Err: NEWTYPE: TYPENAME: namespace: ROOT name: HttpError ");Arbitrary facet attributes
Types that are explictly annotated as belonging to a specific namespace are emitted as separate modules. In Swift this means they are a separate target in the current package. In Java, they are emitted as a child namespace of the package's namespace. In TypeScript they are emitted alongside as a separate .ts
file.
#[derive(Facet)] #[facet(namespace = "server_sent_events")] pub struct SseRequest { pub url: String, } #[derive(Facet)] #[facet(namespace = "server_sent_events")] #[repr(C)] pub enum SseResponse { Chunk(Vec<u8>), Done, }
Struct and Enum renaming doesn't use #[facet(rename = "Effect")]
, as facet doesn't seem to pass it through (yet?). So instead, for now, we use an arbitrary ShapeAttribute
(name
instead of rename
), like this:
#[derive(Facet)] #[facet(name = "Effect")] struct EffectFfi { name: String, active: bool, }Skipping struct fields or enum variants
You can annotate fields or variants with #[facet(skip)]
to prevent them from being emitted in the generated code. (Note: you can also use #[facet(opaque)])
to prevent Facet from recursing through).
#[derive(Facet)] #[repr(C)] pub enum Event { Get, #[facet(skip)] Set(HttpResult<HttpResponse<Count>, HttpError>), }
You can skip through (even successive layers) of newtyping by annotating the struct with #[facet(transparent)]
.
#[test] fn transparent() { #[derive(Facet)] #[facet(transparent)] struct Inner(i32); #[derive(Facet)] struct MyStruct { inner: Inner, } let registry = RegistryBuilder::new().add_type::<MyStruct>().build(); insta::assert_yaml_snapshot!(registry, @r" ? namespace: ROOT name: MyStruct : STRUCT: - inner: I32 "); }
In order to specify BYTES
in the IR (for Vec<u8>
and &'a [u8]
), we can use the #[facet(bytes)]
attribute:
#[derive(Facet)] pub struct HttpResponse { pub status: u16, pub headers: Vec<HttpHeader>, #[facet(bytes)] pub body: Vec<u8>, }
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4