From 0adc36ce1c0aaeff645e6d17d6c7d54c64a5b321 Mon Sep 17 00:00:00 2001 From: inokawa <48897392+inokawa@users.noreply.github.com> Date: Mon, 22 Apr 2024 15:28:04 +0900 Subject: [PATCH] feat(cli): support generation of literal union from string enum (#2054) * feat(cli): support generation of literal union from enum * Remove const --------- Co-authored-by: LongYinan --- cli/src/utils/typegen.ts | 10 ++++++++++ crates/backend/src/ast.rs | 1 + crates/backend/src/typegen/enum.rs | 6 +++++- crates/macro/src/parser/mod.rs | 2 ++ 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/cli/src/utils/typegen.ts b/cli/src/utils/typegen.ts index 5b254b37..73ec6a35 100644 --- a/cli/src/utils/typegen.ts +++ b/cli/src/utils/typegen.ts @@ -10,6 +10,7 @@ export const DEFAULT_TYPE_DEF_HEADER = `/* auto-generated by NAPI-RS */ enum TypeDefKind { Const = 'const', Enum = 'enum', + StringEnum = 'string_enum', Interface = 'interface', Fn = 'fn', Struct = 'struct', @@ -41,6 +42,14 @@ function prettyPrint( s += `export ${enumName} ${line.name} {\n${line.def}\n}` break + case TypeDefKind.StringEnum: + if (constEnum) { + s += `export const enum ${line.name} {\n${line.def}\n}` + } else { + s += `export type ${line.name} = ${line.def.replaceAll(/.*=/g, '').replaceAll(',', '|')};` + } + break + case TypeDefKind.Struct: s += `export class ${line.name} {\n${line.def}\n}` if (line.original_name && line.original_name !== line.name) { @@ -75,6 +84,7 @@ export async function processTypeDef( switch (def.kind) { case TypeDefKind.Const: case TypeDefKind.Enum: + case TypeDefKind.StringEnum: case TypeDefKind.Fn: case TypeDefKind.Struct: { exports.push(def.name) diff --git a/crates/backend/src/ast.rs b/crates/backend/src/ast.rs index 3954c634..3a6eb5d3 100644 --- a/crates/backend/src/ast.rs +++ b/crates/backend/src/ast.rs @@ -136,6 +136,7 @@ pub struct NapiEnum { pub comments: Vec, pub skip_typescript: bool, pub register_name: Ident, + pub is_string_enum: bool, } #[derive(Debug, Clone)] diff --git a/crates/backend/src/typegen/enum.rs b/crates/backend/src/typegen/enum.rs index cdd03780..96f2abda 100644 --- a/crates/backend/src/typegen/enum.rs +++ b/crates/backend/src/typegen/enum.rs @@ -10,7 +10,11 @@ impl ToTypeDef for NapiEnum { add_alias(self.name.to_string(), self.js_name.to_string()); Some(TypeDef { - kind: "enum".to_owned(), + kind: if self.is_string_enum { + "string_enum".to_owned() + } else { + "enum".to_owned() + }, name: self.js_name.to_owned(), original_name: Some(self.name.to_string()), def: self.gen_ts_variants(), diff --git a/crates/macro/src/parser/mod.rs b/crates/macro/src/parser/mod.rs index 837cce46..d0f8377c 100644 --- a/crates/macro/src/parser/mod.rs +++ b/crates/macro/src/parser/mod.rs @@ -1070,6 +1070,7 @@ impl ConvertToAST for syn::ItemEnum { .js_name() .map_or_else(|| self.ident.to_string(), |(s, _)| s.to_string()); + let is_string_enum = opts.string_enum().is_some(); let variants = match opts.string_enum() { Some(case) => { let case = case.map(|c| Ok::(match c.0.as_str() { @@ -1183,6 +1184,7 @@ impl ConvertToAST for syn::ItemEnum { comments: extract_doc_comments(&self.attrs), skip_typescript: opts.skip_typescript().is_some(), register_name: get_register_ident(self.ident.to_string().as_str()), + is_string_enum, }), }) }