A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/redbadger/facet-generate below:

redbadger/facet-generate: Reflect types annotated with #[Facet] into Java, Swift, and TypeScript.

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