Bug 1965313 - Reimplement enum discriminents, r=bgruber
Differential Revision: https://phabricator.services.mozilla.com/D248491
This commit is contained in:
committed by
bdeankawamura@mozilla.com
parent
90368cc237
commit
02d50105b9
@@ -1268,47 +1268,47 @@ export const Interest = {
|
||||
/**
|
||||
* INCONCLUSIVE
|
||||
*/
|
||||
INCONCLUSIVE: 1,
|
||||
INCONCLUSIVE: 0,
|
||||
/**
|
||||
* ANIMALS
|
||||
*/
|
||||
ANIMALS: 2,
|
||||
ANIMALS: 1,
|
||||
/**
|
||||
* ARTS
|
||||
*/
|
||||
ARTS: 3,
|
||||
ARTS: 2,
|
||||
/**
|
||||
* AUTOS
|
||||
*/
|
||||
AUTOS: 4,
|
||||
AUTOS: 3,
|
||||
/**
|
||||
* BUSINESS
|
||||
*/
|
||||
BUSINESS: 5,
|
||||
BUSINESS: 4,
|
||||
/**
|
||||
* CAREER
|
||||
*/
|
||||
CAREER: 6,
|
||||
CAREER: 5,
|
||||
/**
|
||||
* EDUCATION
|
||||
*/
|
||||
EDUCATION: 7,
|
||||
EDUCATION: 6,
|
||||
/**
|
||||
* FASHION
|
||||
*/
|
||||
FASHION: 8,
|
||||
FASHION: 7,
|
||||
/**
|
||||
* FINANCE
|
||||
*/
|
||||
FINANCE: 9,
|
||||
FINANCE: 8,
|
||||
/**
|
||||
* FOOD
|
||||
*/
|
||||
FOOD: 10,
|
||||
FOOD: 9,
|
||||
/**
|
||||
* GOVERNMENT
|
||||
*/
|
||||
GOVERNMENT: 11,
|
||||
GOVERNMENT: 10,
|
||||
/**
|
||||
* HOBBIES
|
||||
*/
|
||||
@@ -1347,6 +1347,7 @@ Object.freeze(Interest);
|
||||
// Export the FFIConverter object to make external types work.
|
||||
export class FfiConverterTypeInterest extends FfiConverterArrayBuffer {
|
||||
static read(dataStream) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
switch (dataStream.readInt32()) {
|
||||
case 1:
|
||||
return Interest.INCONCLUSIVE
|
||||
@@ -1392,6 +1393,7 @@ export class FfiConverterTypeInterest extends FfiConverterArrayBuffer {
|
||||
}
|
||||
|
||||
static write(dataStream, value) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
if (value === Interest.INCONCLUSIVE) {
|
||||
dataStream.writeInt32(1);
|
||||
return;
|
||||
|
||||
@@ -591,6 +591,7 @@ RemoteSettingsServer.Custom = class extends RemoteSettingsServer{
|
||||
// Export the FFIConverter object to make external types work.
|
||||
export class FfiConverterTypeRemoteSettingsServer extends FfiConverterArrayBuffer {
|
||||
static read(dataStream) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
switch (dataStream.readInt32()) {
|
||||
case 1:
|
||||
return new RemoteSettingsServer.Prod(
|
||||
@@ -611,6 +612,7 @@ export class FfiConverterTypeRemoteSettingsServer extends FfiConverterArrayBuffe
|
||||
}
|
||||
|
||||
static write(dataStream, value) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
if (value instanceof RemoteSettingsServer.Prod) {
|
||||
dataStream.writeInt32(1);
|
||||
return;
|
||||
|
||||
@@ -356,17 +356,18 @@ export const JsonEngineMethod = {
|
||||
/**
|
||||
* POST
|
||||
*/
|
||||
POST: 1,
|
||||
POST: 2,
|
||||
/**
|
||||
* GET
|
||||
*/
|
||||
GET: 2,
|
||||
GET: 1,
|
||||
};
|
||||
Object.freeze(JsonEngineMethod);
|
||||
|
||||
// Export the FFIConverter object to make external types work.
|
||||
export class FfiConverterTypeJSONEngineMethod extends FfiConverterArrayBuffer {
|
||||
static read(dataStream) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
switch (dataStream.readInt32()) {
|
||||
case 1:
|
||||
return JsonEngineMethod.POST
|
||||
@@ -378,6 +379,7 @@ export class FfiConverterTypeJSONEngineMethod extends FfiConverterArrayBuffer {
|
||||
}
|
||||
|
||||
static write(dataStream, value) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
if (value === JsonEngineMethod.POST) {
|
||||
dataStream.writeInt32(1);
|
||||
return;
|
||||
@@ -1039,17 +1041,18 @@ export const SearchEngineClassification = {
|
||||
/**
|
||||
* GENERAL
|
||||
*/
|
||||
GENERAL: 1,
|
||||
GENERAL: 2,
|
||||
/**
|
||||
* UNKNOWN
|
||||
*/
|
||||
UNKNOWN: 2,
|
||||
UNKNOWN: 1,
|
||||
};
|
||||
Object.freeze(SearchEngineClassification);
|
||||
|
||||
// Export the FFIConverter object to make external types work.
|
||||
export class FfiConverterTypeSearchEngineClassification extends FfiConverterArrayBuffer {
|
||||
static read(dataStream) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
switch (dataStream.readInt32()) {
|
||||
case 1:
|
||||
return SearchEngineClassification.GENERAL
|
||||
@@ -1061,6 +1064,7 @@ export class FfiConverterTypeSearchEngineClassification extends FfiConverterArra
|
||||
}
|
||||
|
||||
static write(dataStream, value) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
if (value === SearchEngineClassification.GENERAL) {
|
||||
dataStream.writeInt32(1);
|
||||
return;
|
||||
@@ -2044,6 +2048,7 @@ Object.freeze(SearchUpdateChannel);
|
||||
// Export the FFIConverter object to make external types work.
|
||||
export class FfiConverterTypeSearchUpdateChannel extends FfiConverterArrayBuffer {
|
||||
static read(dataStream) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
switch (dataStream.readInt32()) {
|
||||
case 1:
|
||||
return SearchUpdateChannel.NIGHTLY
|
||||
@@ -2063,6 +2068,7 @@ export class FfiConverterTypeSearchUpdateChannel extends FfiConverterArrayBuffer
|
||||
}
|
||||
|
||||
static write(dataStream, value) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
if (value === SearchUpdateChannel.NIGHTLY) {
|
||||
dataStream.writeInt32(1);
|
||||
return;
|
||||
@@ -2131,6 +2137,7 @@ Object.freeze(SearchApplicationName);
|
||||
// Export the FFIConverter object to make external types work.
|
||||
export class FfiConverterTypeSearchApplicationName extends FfiConverterArrayBuffer {
|
||||
static read(dataStream) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
switch (dataStream.readInt32()) {
|
||||
case 1:
|
||||
return SearchApplicationName.FIREFOX_ANDROID
|
||||
@@ -2148,6 +2155,7 @@ export class FfiConverterTypeSearchApplicationName extends FfiConverterArrayBuff
|
||||
}
|
||||
|
||||
static write(dataStream, value) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
if (value === SearchApplicationName.FIREFOX_ANDROID) {
|
||||
dataStream.writeInt32(1);
|
||||
return;
|
||||
@@ -2204,6 +2212,7 @@ Object.freeze(SearchDeviceType);
|
||||
// Export the FFIConverter object to make external types work.
|
||||
export class FfiConverterTypeSearchDeviceType extends FfiConverterArrayBuffer {
|
||||
static read(dataStream) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
switch (dataStream.readInt32()) {
|
||||
case 1:
|
||||
return SearchDeviceType.SMARTPHONE
|
||||
@@ -2217,6 +2226,7 @@ export class FfiConverterTypeSearchDeviceType extends FfiConverterArrayBuffer {
|
||||
}
|
||||
|
||||
static write(dataStream, value) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
if (value === SearchDeviceType.SMARTPHONE) {
|
||||
dataStream.writeInt32(1);
|
||||
return;
|
||||
|
||||
@@ -755,21 +755,22 @@ export const GeonameMatchType = {
|
||||
/**
|
||||
* For U.S. states, abbreviations are the usual two-letter codes ("CA").
|
||||
*/
|
||||
ABBREVIATION: 1,
|
||||
ABBREVIATION: 0,
|
||||
/**
|
||||
* AIRPORT_CODE
|
||||
*/
|
||||
AIRPORT_CODE: 2,
|
||||
AIRPORT_CODE: 1,
|
||||
/**
|
||||
* This includes any names that aren't abbreviations or airport codes.
|
||||
*/
|
||||
NAME: 3,
|
||||
NAME: 2,
|
||||
};
|
||||
Object.freeze(GeonameMatchType);
|
||||
|
||||
// Export the FFIConverter object to make external types work.
|
||||
export class FfiConverterTypeGeonameMatchType extends FfiConverterArrayBuffer {
|
||||
static read(dataStream) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
switch (dataStream.readInt32()) {
|
||||
case 1:
|
||||
return GeonameMatchType.ABBREVIATION
|
||||
@@ -783,6 +784,7 @@ export class FfiConverterTypeGeonameMatchType extends FfiConverterArrayBuffer {
|
||||
}
|
||||
|
||||
static write(dataStream, value) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
if (value === GeonameMatchType.ABBREVIATION) {
|
||||
dataStream.writeInt32(1);
|
||||
return;
|
||||
@@ -1455,6 +1457,7 @@ Suggestion.Dynamic = class extends Suggestion{
|
||||
// Export the FFIConverter object to make external types work.
|
||||
export class FfiConverterTypeSuggestion extends FfiConverterArrayBuffer {
|
||||
static read(dataStream) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
switch (dataStream.readInt32()) {
|
||||
case 1:
|
||||
return new Suggestion.Amp(
|
||||
@@ -1552,6 +1555,7 @@ export class FfiConverterTypeSuggestion extends FfiConverterArrayBuffer {
|
||||
}
|
||||
|
||||
static write(dataStream, value) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
if (value instanceof Suggestion.Amp) {
|
||||
dataStream.writeInt32(1);
|
||||
FfiConverterString.write(dataStream, value.title);
|
||||
@@ -2070,6 +2074,7 @@ Object.freeze(SuggestionProvider);
|
||||
// Export the FFIConverter object to make external types work.
|
||||
export class FfiConverterTypeSuggestionProvider extends FfiConverterArrayBuffer {
|
||||
static read(dataStream) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
switch (dataStream.readInt32()) {
|
||||
case 1:
|
||||
return SuggestionProvider.AMP
|
||||
@@ -2095,6 +2100,7 @@ export class FfiConverterTypeSuggestionProvider extends FfiConverterArrayBuffer
|
||||
}
|
||||
|
||||
static write(dataStream, value) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
if (value === SuggestionProvider.AMP) {
|
||||
dataStream.writeInt32(1);
|
||||
return;
|
||||
@@ -2327,6 +2333,7 @@ Object.freeze(AmpMatchingStrategy);
|
||||
// Export the FFIConverter object to make external types work.
|
||||
export class FfiConverterTypeAmpMatchingStrategy extends FfiConverterArrayBuffer {
|
||||
static read(dataStream) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
switch (dataStream.readInt32()) {
|
||||
case 1:
|
||||
return AmpMatchingStrategy.NO_KEYWORD_EXPANSION
|
||||
@@ -2340,6 +2347,7 @@ export class FfiConverterTypeAmpMatchingStrategy extends FfiConverterArrayBuffer
|
||||
}
|
||||
|
||||
static write(dataStream, value) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
if (value === AmpMatchingStrategy.NO_KEYWORD_EXPANSION) {
|
||||
dataStream.writeInt32(1);
|
||||
return;
|
||||
@@ -2925,17 +2933,18 @@ export const GeonameType = {
|
||||
/**
|
||||
* CITY
|
||||
*/
|
||||
CITY: 1,
|
||||
CITY: 0,
|
||||
/**
|
||||
* REGION
|
||||
*/
|
||||
REGION: 2,
|
||||
REGION: 1,
|
||||
};
|
||||
Object.freeze(GeonameType);
|
||||
|
||||
// Export the FFIConverter object to make external types work.
|
||||
export class FfiConverterTypeGeonameType extends FfiConverterArrayBuffer {
|
||||
static read(dataStream) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
switch (dataStream.readInt32()) {
|
||||
case 1:
|
||||
return GeonameType.CITY
|
||||
@@ -2947,6 +2956,7 @@ export class FfiConverterTypeGeonameType extends FfiConverterArrayBuffer {
|
||||
}
|
||||
|
||||
static write(dataStream, value) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
if (value === GeonameType.CITY) {
|
||||
dataStream.writeInt32(1);
|
||||
return;
|
||||
@@ -2976,22 +2986,23 @@ export const InterruptKind = {
|
||||
/**
|
||||
* Interrupt read operations like [SuggestStore::query]
|
||||
*/
|
||||
READ: 1,
|
||||
READ: 0,
|
||||
/**
|
||||
* Interrupt write operations. This mostly means [SuggestStore::ingest], but
|
||||
* other operations may also be interrupted.
|
||||
*/
|
||||
WRITE: 2,
|
||||
WRITE: 1,
|
||||
/**
|
||||
* Interrupt both read and write operations,
|
||||
*/
|
||||
READ_WRITE: 3,
|
||||
READ_WRITE: 2,
|
||||
};
|
||||
Object.freeze(InterruptKind);
|
||||
|
||||
// Export the FFIConverter object to make external types work.
|
||||
export class FfiConverterTypeInterruptKind extends FfiConverterArrayBuffer {
|
||||
static read(dataStream) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
switch (dataStream.readInt32()) {
|
||||
case 1:
|
||||
return InterruptKind.READ
|
||||
@@ -3005,6 +3016,7 @@ export class FfiConverterTypeInterruptKind extends FfiConverterArrayBuffer {
|
||||
}
|
||||
|
||||
static write(dataStream, value) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
if (value === InterruptKind.READ) {
|
||||
dataStream.writeInt32(1);
|
||||
return;
|
||||
@@ -3197,6 +3209,7 @@ SuggestProviderConfig.Weather = class extends SuggestProviderConfig{
|
||||
// Export the FFIConverter object to make external types work.
|
||||
export class FfiConverterTypeSuggestProviderConfig extends FfiConverterArrayBuffer {
|
||||
static read(dataStream) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
switch (dataStream.readInt32()) {
|
||||
case 1:
|
||||
return new SuggestProviderConfig.Weather(
|
||||
@@ -3209,6 +3222,7 @@ export class FfiConverterTypeSuggestProviderConfig extends FfiConverterArrayBuff
|
||||
}
|
||||
|
||||
static write(dataStream, value) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
if (value instanceof SuggestProviderConfig.Weather) {
|
||||
dataStream.writeInt32(1);
|
||||
FfiConverterFloat64.write(dataStream, value.score);
|
||||
|
||||
@@ -293,33 +293,34 @@ export const DeviceType = {
|
||||
/**
|
||||
* DESKTOP
|
||||
*/
|
||||
DESKTOP: 1,
|
||||
DESKTOP: 0,
|
||||
/**
|
||||
* MOBILE
|
||||
*/
|
||||
MOBILE: 2,
|
||||
MOBILE: 1,
|
||||
/**
|
||||
* TABLET
|
||||
*/
|
||||
TABLET: 3,
|
||||
TABLET: 2,
|
||||
/**
|
||||
* VR
|
||||
*/
|
||||
VR: 4,
|
||||
VR: 3,
|
||||
/**
|
||||
* TV
|
||||
*/
|
||||
TV: 5,
|
||||
TV: 4,
|
||||
/**
|
||||
* UNKNOWN
|
||||
*/
|
||||
UNKNOWN: 6,
|
||||
UNKNOWN: 5,
|
||||
};
|
||||
Object.freeze(DeviceType);
|
||||
|
||||
// Export the FFIConverter object to make external types work.
|
||||
export class FfiConverterTypeDeviceType extends FfiConverterArrayBuffer {
|
||||
static read(dataStream) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
switch (dataStream.readInt32()) {
|
||||
case 1:
|
||||
return DeviceType.DESKTOP
|
||||
@@ -339,6 +340,7 @@ export class FfiConverterTypeDeviceType extends FfiConverterArrayBuffer {
|
||||
}
|
||||
|
||||
static write(dataStream, value) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
if (value === DeviceType.DESKTOP) {
|
||||
dataStream.writeInt32(1);
|
||||
return;
|
||||
|
||||
@@ -842,6 +842,7 @@ RemoteCommand.CloseTab = class extends RemoteCommand{
|
||||
// Export the FFIConverter object to make external types work.
|
||||
export class FfiConverterTypeRemoteCommand extends FfiConverterArrayBuffer {
|
||||
static read(dataStream) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
switch (dataStream.readInt32()) {
|
||||
case 1:
|
||||
return new RemoteCommand.CloseTab(
|
||||
@@ -853,6 +854,7 @@ export class FfiConverterTypeRemoteCommand extends FfiConverterArrayBuffer {
|
||||
}
|
||||
|
||||
static write(dataStream, value) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
if (value instanceof RemoteCommand.CloseTab) {
|
||||
dataStream.writeInt32(1);
|
||||
FfiConverterString.write(dataStream, value.url);
|
||||
|
||||
@@ -693,21 +693,22 @@ export const QuotaReason = {
|
||||
/**
|
||||
* TOTAL_BYTES
|
||||
*/
|
||||
TOTAL_BYTES: 1,
|
||||
TOTAL_BYTES: 0,
|
||||
/**
|
||||
* ITEM_BYTES
|
||||
*/
|
||||
ITEM_BYTES: 2,
|
||||
ITEM_BYTES: 1,
|
||||
/**
|
||||
* MAX_ITEMS
|
||||
*/
|
||||
MAX_ITEMS: 3,
|
||||
MAX_ITEMS: 2,
|
||||
};
|
||||
Object.freeze(QuotaReason);
|
||||
|
||||
// Export the FFIConverter object to make external types work.
|
||||
export class FfiConverterTypeQuotaReason extends FfiConverterArrayBuffer {
|
||||
static read(dataStream) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
switch (dataStream.readInt32()) {
|
||||
case 1:
|
||||
return QuotaReason.TOTAL_BYTES
|
||||
@@ -721,6 +722,7 @@ export class FfiConverterTypeQuotaReason extends FfiConverterArrayBuffer {
|
||||
}
|
||||
|
||||
static write(dataStream, value) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
if (value === QuotaReason.TOTAL_BYTES) {
|
||||
dataStream.writeInt32(1);
|
||||
return;
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use super::*;
|
||||
|
||||
pub fn pass(en: &mut Enum) -> Result<()> {
|
||||
// Determine the actual discriminants for each variant.
|
||||
//
|
||||
// TODO: the UniFFI general pipeline should probably do this. If this was introduced earlier
|
||||
// in the pipeline, we wouldn't need to hand-code so many fields.
|
||||
en.resolved_discr_type = match &en.discr_type {
|
||||
Some(type_node) => type_node.clone(),
|
||||
None => TypeNode {
|
||||
ty: Type::UInt8,
|
||||
canonical_name: "UInt8".to_string(),
|
||||
ffi_converter: "FfiConverterUInt8".to_string(),
|
||||
is_used_as_error: false,
|
||||
ffi_type: FfiTypeNode {
|
||||
ty: FfiType::UInt8,
|
||||
type_name: "uint8_t".to_string(),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
let discr_type = &en.resolved_discr_type;
|
||||
let mut last_variant: Option<&Variant> = None;
|
||||
for variant in en.variants.iter_mut() {
|
||||
match &variant.discr {
|
||||
None => {
|
||||
let lit = match last_variant {
|
||||
None => match &discr_type.ty {
|
||||
Type::UInt8 | Type::UInt16 | Type::UInt32 | Type::UInt64 => {
|
||||
Literal::UInt(0, Radix::Decimal, discr_type.clone())
|
||||
}
|
||||
Type::Int8 | Type::Int16 | Type::Int32 | Type::Int64 => {
|
||||
Literal::Int(0, Radix::Decimal, discr_type.clone())
|
||||
}
|
||||
ty => bail!("Invalid enum discriminant type: {ty:?}"),
|
||||
},
|
||||
Some(variant) => match &variant.resolved_discr.lit {
|
||||
Literal::UInt(val, _, _) => {
|
||||
Literal::UInt(val + 1, Radix::Decimal, discr_type.clone())
|
||||
}
|
||||
Literal::Int(val, _, _) => {
|
||||
Literal::Int(val + 1, Radix::Decimal, discr_type.clone())
|
||||
}
|
||||
lit => bail!("Invalid enum discriminant literal: {lit:?}"),
|
||||
},
|
||||
};
|
||||
variant.resolved_discr = LiteralNode {
|
||||
lit,
|
||||
..LiteralNode::default()
|
||||
};
|
||||
}
|
||||
Some(lit_node) => {
|
||||
variant.resolved_discr = lit_node.clone();
|
||||
}
|
||||
}
|
||||
last_variant = Some(variant);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -12,6 +12,7 @@ mod cpp_ffi_types;
|
||||
mod cpp_names;
|
||||
mod cpp_scaffolding_calls;
|
||||
mod docs;
|
||||
mod enums;
|
||||
mod interfaces;
|
||||
mod js_docstrings;
|
||||
mod js_filename;
|
||||
@@ -21,7 +22,7 @@ mod modules;
|
||||
mod types;
|
||||
|
||||
use crate::Config;
|
||||
use anyhow::Result;
|
||||
use anyhow::{bail, Result};
|
||||
pub use nodes::*;
|
||||
use std::collections::HashMap;
|
||||
use uniffi_bindgen::pipeline::{general, initial};
|
||||
@@ -33,6 +34,7 @@ pub fn gecko_js_pipeline(pipeline_map: HashMap<String, Config>) -> GeckoPipeline
|
||||
general::pipeline()
|
||||
.convert_ir_pass::<Root>()
|
||||
.pass(modules::pass(pipeline_map))
|
||||
.pass(enums::pass)
|
||||
.pass(callables::pass)
|
||||
.pass(interfaces::pass)
|
||||
.pass(callback_interfaces::pass)
|
||||
|
||||
@@ -301,6 +301,7 @@ pub struct Enum {
|
||||
pub remote: bool,
|
||||
pub variants: Vec<Variant>,
|
||||
pub discr_type: Option<TypeNode>,
|
||||
pub resolved_discr_type: TypeNode,
|
||||
pub non_exhaustive: bool,
|
||||
pub js_docstring: String,
|
||||
pub docstring: Option<String>,
|
||||
@@ -312,6 +313,7 @@ pub struct Enum {
|
||||
pub struct Variant {
|
||||
pub name: String,
|
||||
pub discr: Option<LiteralNode>,
|
||||
pub resolved_discr: LiteralNode,
|
||||
pub fields: Vec<Field>,
|
||||
pub docstring: Option<String>,
|
||||
pub js_docstring: String,
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
export const {{ enum_.name }} = {
|
||||
{%- for variant in enum_.variants %}
|
||||
{{ variant.js_docstring|indent(4) }}
|
||||
{{ variant.name }}: {{loop.index}},
|
||||
{{ variant.name }}: {{ variant.resolved_discr.js_lit }},
|
||||
{%- endfor %}
|
||||
};
|
||||
Object.freeze({{ enum_.name }});
|
||||
@@ -12,6 +12,7 @@ Object.freeze({{ enum_.name }});
|
||||
// Export the FFIConverter object to make external types work.
|
||||
export class {{ enum_|ffi_converter }} extends FfiConverterArrayBuffer {
|
||||
static read(dataStream) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
switch (dataStream.readInt32()) {
|
||||
{%- for variant in enum_.variants %}
|
||||
case {{ loop.index }}:
|
||||
@@ -23,6 +24,7 @@ export class {{ enum_|ffi_converter }} extends FfiConverterArrayBuffer {
|
||||
}
|
||||
|
||||
static write(dataStream, value) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
{%- for variant in enum_.variants %}
|
||||
if (value === {{ enum_.name }}.{{ variant.name }}) {
|
||||
dataStream.writeInt32({{ loop.index }});
|
||||
@@ -67,6 +69,7 @@ export class {{ enum_.name }} {}
|
||||
// Export the FFIConverter object to make external types work.
|
||||
export class {{ enum_|ffi_converter }} extends FfiConverterArrayBuffer {
|
||||
static read(dataStream) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
switch (dataStream.readInt32()) {
|
||||
{%- for variant in enum_.variants %}
|
||||
case {{ loop.index }}:
|
||||
@@ -82,6 +85,7 @@ export class {{ enum_|ffi_converter }} extends FfiConverterArrayBuffer {
|
||||
}
|
||||
|
||||
static write(dataStream, value) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
{%- for variant in enum_.variants %}
|
||||
if (value instanceof {{ enum_.name }}.{{ variant.name }}) {
|
||||
dataStream.writeInt32({{ loop.index }});
|
||||
|
||||
@@ -2264,21 +2264,22 @@ export const EnumNoData = {
|
||||
/**
|
||||
* A
|
||||
*/
|
||||
A: 1,
|
||||
A: 0,
|
||||
/**
|
||||
* B
|
||||
*/
|
||||
B: 2,
|
||||
B: 1,
|
||||
/**
|
||||
* C
|
||||
*/
|
||||
C: 3,
|
||||
C: 2,
|
||||
};
|
||||
Object.freeze(EnumNoData);
|
||||
|
||||
// Export the FFIConverter object to make external types work.
|
||||
export class FfiConverterTypeEnumNoData extends FfiConverterArrayBuffer {
|
||||
static read(dataStream) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
switch (dataStream.readInt32()) {
|
||||
case 1:
|
||||
return EnumNoData.A
|
||||
@@ -2292,6 +2293,7 @@ export class FfiConverterTypeEnumNoData extends FfiConverterArrayBuffer {
|
||||
}
|
||||
|
||||
static write(dataStream, value) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
if (value === EnumNoData.A) {
|
||||
dataStream.writeInt32(1);
|
||||
return;
|
||||
@@ -2357,6 +2359,7 @@ EnumWithData.C = class extends EnumWithData{
|
||||
// Export the FFIConverter object to make external types work.
|
||||
export class FfiConverterTypeEnumWithData extends FfiConverterArrayBuffer {
|
||||
static read(dataStream) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
switch (dataStream.readInt32()) {
|
||||
case 1:
|
||||
return new EnumWithData.A(
|
||||
@@ -2375,6 +2378,7 @@ export class FfiConverterTypeEnumWithData extends FfiConverterArrayBuffer {
|
||||
}
|
||||
|
||||
static write(dataStream, value) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
if (value instanceof EnumWithData.A) {
|
||||
dataStream.writeInt32(1);
|
||||
FfiConverterUInt8.write(dataStream, value.value);
|
||||
@@ -2457,6 +2461,7 @@ ComplexEnum.C = class extends ComplexEnum{
|
||||
// Export the FFIConverter object to make external types work.
|
||||
export class FfiConverterTypeComplexEnum extends FfiConverterArrayBuffer {
|
||||
static read(dataStream) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
switch (dataStream.readInt32()) {
|
||||
case 1:
|
||||
return new ComplexEnum.A(
|
||||
@@ -2476,6 +2481,7 @@ export class FfiConverterTypeComplexEnum extends FfiConverterArrayBuffer {
|
||||
}
|
||||
|
||||
static write(dataStream, value) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
if (value instanceof ComplexEnum.A) {
|
||||
dataStream.writeInt32(1);
|
||||
FfiConverterTypeEnumNoData.write(dataStream, value.value);
|
||||
@@ -2519,6 +2525,162 @@ export class FfiConverterTypeComplexEnum extends FfiConverterArrayBuffer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ExplicitValuedEnum
|
||||
*/
|
||||
export const ExplicitValuedEnum = {
|
||||
/**
|
||||
* FIRST
|
||||
*/
|
||||
FIRST: 1,
|
||||
/**
|
||||
* SECOND
|
||||
*/
|
||||
SECOND: 2,
|
||||
/**
|
||||
* FOURTH
|
||||
*/
|
||||
FOURTH: 4,
|
||||
/**
|
||||
* TENTH
|
||||
*/
|
||||
TENTH: 10,
|
||||
/**
|
||||
* ELEVENTH
|
||||
*/
|
||||
ELEVENTH: 11,
|
||||
/**
|
||||
* THIRTEENTH
|
||||
*/
|
||||
THIRTEENTH: 13,
|
||||
};
|
||||
Object.freeze(ExplicitValuedEnum);
|
||||
|
||||
// Export the FFIConverter object to make external types work.
|
||||
export class FfiConverterTypeExplicitValuedEnum extends FfiConverterArrayBuffer {
|
||||
static read(dataStream) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
switch (dataStream.readInt32()) {
|
||||
case 1:
|
||||
return ExplicitValuedEnum.FIRST
|
||||
case 2:
|
||||
return ExplicitValuedEnum.SECOND
|
||||
case 3:
|
||||
return ExplicitValuedEnum.FOURTH
|
||||
case 4:
|
||||
return ExplicitValuedEnum.TENTH
|
||||
case 5:
|
||||
return ExplicitValuedEnum.ELEVENTH
|
||||
case 6:
|
||||
return ExplicitValuedEnum.THIRTEENTH
|
||||
default:
|
||||
throw new UniFFITypeError("Unknown ExplicitValuedEnum variant");
|
||||
}
|
||||
}
|
||||
|
||||
static write(dataStream, value) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
if (value === ExplicitValuedEnum.FIRST) {
|
||||
dataStream.writeInt32(1);
|
||||
return;
|
||||
}
|
||||
if (value === ExplicitValuedEnum.SECOND) {
|
||||
dataStream.writeInt32(2);
|
||||
return;
|
||||
}
|
||||
if (value === ExplicitValuedEnum.FOURTH) {
|
||||
dataStream.writeInt32(3);
|
||||
return;
|
||||
}
|
||||
if (value === ExplicitValuedEnum.TENTH) {
|
||||
dataStream.writeInt32(4);
|
||||
return;
|
||||
}
|
||||
if (value === ExplicitValuedEnum.ELEVENTH) {
|
||||
dataStream.writeInt32(5);
|
||||
return;
|
||||
}
|
||||
if (value === ExplicitValuedEnum.THIRTEENTH) {
|
||||
dataStream.writeInt32(6);
|
||||
return;
|
||||
}
|
||||
throw new UniFFITypeError("Unknown ExplicitValuedEnum variant");
|
||||
}
|
||||
|
||||
static computeSize(value) {
|
||||
return 4;
|
||||
}
|
||||
|
||||
static checkType(value) {
|
||||
if (!Number.isInteger(value) || value < 1 || value > 6) {
|
||||
throw new UniFFITypeError(`${value} is not a valid value for ExplicitValuedEnum`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* GappedEnum
|
||||
*/
|
||||
export const GappedEnum = {
|
||||
/**
|
||||
* ONE
|
||||
*/
|
||||
ONE: 10,
|
||||
/**
|
||||
* TWO
|
||||
*/
|
||||
TWO: 11,
|
||||
/**
|
||||
* THREE
|
||||
*/
|
||||
THREE: 14,
|
||||
};
|
||||
Object.freeze(GappedEnum);
|
||||
|
||||
// Export the FFIConverter object to make external types work.
|
||||
export class FfiConverterTypeGappedEnum extends FfiConverterArrayBuffer {
|
||||
static read(dataStream) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
switch (dataStream.readInt32()) {
|
||||
case 1:
|
||||
return GappedEnum.ONE
|
||||
case 2:
|
||||
return GappedEnum.TWO
|
||||
case 3:
|
||||
return GappedEnum.THREE
|
||||
default:
|
||||
throw new UniFFITypeError("Unknown GappedEnum variant");
|
||||
}
|
||||
}
|
||||
|
||||
static write(dataStream, value) {
|
||||
// Use sequential indices (1-based) for the wire format to match the Rust scaffolding
|
||||
if (value === GappedEnum.ONE) {
|
||||
dataStream.writeInt32(1);
|
||||
return;
|
||||
}
|
||||
if (value === GappedEnum.TWO) {
|
||||
dataStream.writeInt32(2);
|
||||
return;
|
||||
}
|
||||
if (value === GappedEnum.THREE) {
|
||||
dataStream.writeInt32(3);
|
||||
return;
|
||||
}
|
||||
throw new UniFFITypeError("Unknown GappedEnum variant");
|
||||
}
|
||||
|
||||
static computeSize(value) {
|
||||
return 4;
|
||||
}
|
||||
|
||||
static checkType(value) {
|
||||
if (!Number.isInteger(value) || value < 1 || value > 3) {
|
||||
throw new UniFFITypeError(`${value} is not a valid value for GappedEnum`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Error enum
|
||||
*/
|
||||
|
||||
@@ -5,9 +5,11 @@ const {
|
||||
roundtripEnumNoData,
|
||||
roundtripEnumWithData,
|
||||
roundtripComplexEnum,
|
||||
ComplexEnum,
|
||||
EnumNoData,
|
||||
EnumWithData,
|
||||
ComplexEnum,
|
||||
ExplicitValuedEnum,
|
||||
GappedEnum,
|
||||
SimpleRec,
|
||||
} = ChromeUtils.importESModule(
|
||||
"resource://gre/modules/RustUniffiBindingsTests.sys.mjs"
|
||||
@@ -40,3 +42,23 @@ Assert.deepEqual(
|
||||
roundtripComplexEnum(new ComplexEnum.C(new SimpleRec({ a: 30 }))),
|
||||
new ComplexEnum.C(new SimpleRec({ a: 30 }))
|
||||
);
|
||||
|
||||
// Test that the enum discriminant values
|
||||
|
||||
// No discriminant specified, start at 0 then increment by 1
|
||||
Assert.equal(EnumNoData.A, 0);
|
||||
Assert.equal(EnumNoData.B, 1);
|
||||
Assert.equal(EnumNoData.C, 2);
|
||||
|
||||
// All discriminants specified, use the specified values
|
||||
Assert.equal(ExplicitValuedEnum.FIRST, 1);
|
||||
Assert.equal(ExplicitValuedEnum.SECOND, 2);
|
||||
Assert.equal(ExplicitValuedEnum.FOURTH, 4);
|
||||
Assert.equal(ExplicitValuedEnum.TENTH, 10);
|
||||
Assert.equal(ExplicitValuedEnum.ELEVENTH, 11);
|
||||
Assert.equal(ExplicitValuedEnum.THIRTEENTH, 13);
|
||||
|
||||
// Some discriminants specified, increment by one for any unspecified variants
|
||||
Assert.equal(GappedEnum.ONE, 10);
|
||||
Assert.equal(GappedEnum.TWO, 11); // Sequential value after ONE (10+1)
|
||||
Assert.equal(GappedEnum.THREE, 14); // Explicit value again
|
||||
|
||||
@@ -25,6 +25,27 @@ pub enum ComplexEnum {
|
||||
C { value: SimpleRec },
|
||||
}
|
||||
|
||||
// Test enum with explicit discriminant values and gaps
|
||||
#[repr(u8)]
|
||||
#[derive(Debug, Clone, Copy, uniffi::Enum)]
|
||||
pub enum ExplicitValuedEnum {
|
||||
First = 1,
|
||||
Second = 2,
|
||||
Fourth = 4,
|
||||
Tenth = 10,
|
||||
Eleventh = 11,
|
||||
Thirteenth = 13,
|
||||
}
|
||||
|
||||
// Example with sequential and explicit values mixed
|
||||
#[repr(u8)]
|
||||
#[derive(Debug, Clone, Copy, uniffi::Enum)]
|
||||
pub enum GappedEnum {
|
||||
One = 10,
|
||||
Two, // should be 11
|
||||
Three = 14,
|
||||
}
|
||||
|
||||
#[uniffi::export]
|
||||
pub fn roundtrip_enum_no_data(en: EnumNoData) -> EnumNoData {
|
||||
en
|
||||
|
||||
Reference in New Issue
Block a user