枚举
WARNING
JavaScript 中没有 enum,并且 Rust 中的 enum 与 TypeScript 中的 enum
有很大的不同。 在 JavaScript 中使用 Rust enum 之前,你需要仔细阅读本节内容。
在 NAPI-RS 中,Rust enum 被转换为普通的 JavaScript 对象。
#[napi]
pub enum Kind {
Duck,
Dog,
Cat,
}
⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️
export const enum Kind {
Duck,
Dog,
Cat,
}
在 TypeScript 中,数字 enums 成员还会获得从枚举值到枚举名称的反向映射。
但在 Rust 中,我们没有这种反向映射行为,它只是一个普通的 JavaScript 对象。
数字变体默认使用从零开始的连续 i32 值。显式的 Rust 整数判别值会被保留,之后的隐式变体会从前一个值继续递增。
字符串枚举
#[napi(string_enum)]
pub enum Kind {
Duck,
Dog,
Cat,
}
⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️
export const enum Kind {
Duck = 'Duck',
Dog = 'Dog',
Cat = 'Cat',
}
使用 string_enum = "case" 可以转换所有变体名称,也可以在单个变体上使用 #[napi(value = "...")] 来指定确切的 JavaScript 值。支持的大小写形式列在 #[napi] 属性参考中。
#[napi(string_enum = "kebab-case")]
pub enum AccessMode {
ReadOnly,
#[napi(value = "read-write")]
Writable,
}
结构化枚举
只要一个枚举包含携带数据的变体,它就会变成可辨识对象联合,而不是 JavaScript 枚举对象。
#[napi]
pub enum Event {
Ready,
FileChanged { path: String },
Progress(u32, u32),
}
export type Event =
| { type: 'Ready' }
| { type: 'FileChanged'; path: string }
| { type: 'Progress'; field0: number; field1: number }
判别字段默认为 type。使用 discriminant = "kind" 可以改变它,使用 discriminant_case = "camelCase" 或其他支持的形式可以转换变体值。具名变体字段会保留其名称;元组字段会变成 field0、field1,依此类推。字段的 JavaScript 名称不能与判别字段相同。
结构化枚举转换拥有所有权:接收枚举时会读取其字段并将其转换为 Rust 枚举值,返回枚举时则会创建新的 JavaScript 对象。object_from_js = false 或 object_to_js = false 可以让类型变为单向转换。参阅类型转换。
NAPI-RS 不支持将 Rust enum 的 impl 生成到 JavaScript 中。