Skip to content

redbadger/facet-generate

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

33 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

facet-generate · GitHub license Crate version Docs Build status

An adapter to reflect types annotated with #[Facet] into the Intermediate Representation (IR) used by serde-generate (which generates code for C++, Java, Python, Rust, Go, C#, Swift, OCaml, and Dart).

Note:

Currently, struct and enum renaming is not fully implemented and probably requires an upstream PR to facet.

Usage

cargo add facet facet-generate
use facet::Facet;

#[derive(Facet)]
#[repr(C)]
pub enum HttpResult {
    Ok(HttpResponse),
    Err(HttpError),
}

#[derive(Facet)]
pub struct HttpResponse {
    pub status: u16,
    pub headers: Vec<HttpHeader>,
    #[facet(bytes)]
    pub body: Vec<u8>,
}

#[derive(Facet)]
pub struct HttpHeader {
    pub name: String,
    pub value: String,
}

#[derive(Facet)]
#[repr(C)]
pub enum HttpError {
    #[facet(skip)]
    Http {
        status: u16,
        message: String,
        body: Option<Vec<u8>>,
    },
    #[facet(skip)]
    Json(String),
    Url(String),
    Io(String),
    Timeout,
}

let registry = facet_generate::reflect::<HttpResult>();
insta::assert_yaml_snapshot!(registry.containers, @r"
HttpError:
  ENUM:
    0:
      Url:
        NEWTYPE: STR
    1:
      Io:
        NEWTYPE: STR
    2:
      Timeout: UNIT
HttpHeader:
  STRUCT:
    - name: STR
    - value: STR
HttpResponse:
  STRUCT:
    - status: U16
    - headers:
        SEQ:
          TYPENAME: HttpHeader
    - body: BYTES
HttpResult:
  ENUM:
    0:
      Ok:
        NEWTYPE:
          TYPENAME: HttpResponse
    1:
      Err:
        NEWTYPE:
          TYPENAME: HttpError
");

Arbitrary facet attributes

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,
}

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>,
}

About

Generate IR for `serde-generate` from types annotated with `#[Facet]`

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published