Wulf / tsync

Synchronize rust and typescript types!
Other
116 stars 10 forks source link

feat: implement support for serde flatten #49

Closed rlcurrall closed 5 months ago

rlcurrall commented 9 months ago

Addresses #48

Will convert these Rust types:

#[tsync]
#[derive(Serialize)]
/// Struct with flattened field.
struct Author {
    name: String,
    #[serde(flatten)]
    name: AuthorName,
}

#[tsync]
#[derive(Serialize)]
struct AuthorName {
    alias: Option<String>,
    first_name: String,
    last_name: String,
}

To these TypeScript types:

/** Struct with flattened field. */
export type Author = AuthorName & {
  name: string;
}

export interface AuthorName {
  alias?: string;
  first_name: string;
  last_name: string;
}

It also supports enums, so the following Rust types:

/// Doc comments are preserved too!
#[tsync]
struct Book {
    /// Name of the book.
    name: String,
    /// Chapters of the book.
    chapters: Vec<Chapter>,
    /// Reviews of the book
    /// by users.
    user_reviews: Option<Vec<String>>,
    #[serde(flatten)]
    book_type: BookType,
}

#[tsync]
#[derive(Serialize)]
#[serde(tag = "type")]
enum BookType {
    Fiction { genre: String },
    NonFiction { subject: String },
}

Will generate these TypeScript types:

/** Doc comments are preserved too! */
export type Book = BookType & {
  /** Name of the book. */
  name: string;
  /** Chapters of the book. */
  chapters: Array<Chapter>;
  /**
   * Reviews of the book
   * by users.
   */
  user_reviews?: Array<string>;
}

export type BookType =
  | BookType__Fiction
  | BookType__NonFiction;

type BookType__Fiction = {
  type: "Fiction";
  genre: string;
};
type BookType__NonFiction = {
  type: "NonFiction";
  subject: string;
};