// This file was autogenerated by the `uniffi-bindgen-gecko-js` crate.
// Trust me, you don't want to mess with it!

import {
  ArrayBufferDataStream,
  FfiConverter,
  FfiConverterArrayBuffer,
  FfiConverterInt8,
  FfiConverterUInt8,
  FfiConverterInt16,
  FfiConverterUInt16,
  FfiConverterInt32,
  FfiConverterUInt32,
  FfiConverterInt64,
  FfiConverterUInt64,
  FfiConverterFloat32,
  FfiConverterFloat64,
  FfiConverterBoolean,
  FfiConverterBytes,
  FfiConverterString,
  UniFFICallbackHandler,
  UniFFICallbackMethodHandler,
  UniFFIError,
  UniFFIInternalError,
  UniFFITypeError,
  constructUniffiObject,
  handleRustResult,
  uniffiObjectPtr,
} from "moz-src:///toolkit/components/uniffi-js/js/UniFFI.sys.mjs";

// Objects intended to be used in the unit tests
export var UnitTestObjs = {
    uniffiObjectPtr,
};



// Export the FFIConverter object to make external types work.
export class FfiConverterOptionalString extends FfiConverterArrayBuffer {
    static checkType(value) {
        if (value !== undefined && value !== null) {
            FfiConverterString.checkType(value)
        }
    }

    static read(dataStream) {
        const code = dataStream.readUint8(0);
        switch (code) {
            case 0:
                return null
            case 1:
                return FfiConverterString.read(dataStream)
            default:
                throw new UniFFIError(`Unexpected code: ${code}`);
        }
    }

    static write(dataStream, value) {
        if (value === null || value === undefined) {
            dataStream.writeUint8(0);
            return;
        }
        dataStream.writeUint8(1);
        FfiConverterString.write(dataStream, value)
    }

    static computeSize(value) {
        if (value === null || value === undefined) {
            return 1;
        }
        return 1 + FfiConverterString.computeSize(value)
    }
}

/**
 * The list of possible submission methods for search engine urls.
 */
export const JsonEngineMethod = Object.freeze({
    /**
     * POST
     */
    POST: 2,
    /**
     * GET
     */
    GET: 1,
});

// Export the FFIConverter object to make external types work.
export class FfiConverterTypeJSONEngineMethod extends FfiConverterArrayBuffer {
    static #validValues = Object.values(JsonEngineMethod)

    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
            case 2:
                return JsonEngineMethod.GET
            default:
                throw new UniFFITypeError("Unknown JsonEngineMethod variant");
        }
    }

    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;
        }
        if (value === JsonEngineMethod.GET) {
            dataStream.writeInt32(2);
            return;
        }
        throw new UniFFITypeError("Unknown JsonEngineMethod variant");
    }

    static computeSize(value) {
        return 4;
    }

    static checkType(value) {
      // Check that the value is a valid enum variant
      if (!this.#validValues.includes(value)) {
          throw new UniFFITypeError(`${value} is not a valid value for JsonEngineMethod`);
      }
    }
}
// Export the FFIConverter object to make external types work.
export class FfiConverterOptionalTypeJSONEngineMethod extends FfiConverterArrayBuffer {
    static checkType(value) {
        if (value !== undefined && value !== null) {
            FfiConverterTypeJSONEngineMethod.checkType(value)
        }
    }

    static read(dataStream) {
        const code = dataStream.readUint8(0);
        switch (code) {
            case 0:
                return null
            case 1:
                return FfiConverterTypeJSONEngineMethod.read(dataStream)
            default:
                throw new UniFFIError(`Unexpected code: ${code}`);
        }
    }

    static write(dataStream, value) {
        if (value === null || value === undefined) {
            dataStream.writeUint8(0);
            return;
        }
        dataStream.writeUint8(1);
        FfiConverterTypeJSONEngineMethod.write(dataStream, value)
    }

    static computeSize(value) {
        if (value === null || value === undefined) {
            return 1;
        }
        return 1 + FfiConverterTypeJSONEngineMethod.computeSize(value)
    }
}
/**
 * Parameter definitions for search engine URLs. The name property is always
 * specified, along with one of value, experiment_config or search_access_point.
 */
export class SearchUrlParam {
    constructor(
        {
            name, 
            value, 
            enterpriseValue, 
            experimentConfig
        } = {
            name: undefined, 
            value: undefined, 
            enterpriseValue: undefined, 
            experimentConfig: undefined
        }
    ) {
        try {
            FfiConverterString.checkType(name)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("name");
            }
            throw e;
        }
        try {
            FfiConverterOptionalString.checkType(value)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("value");
            }
            throw e;
        }
        try {
            FfiConverterOptionalString.checkType(enterpriseValue)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("enterpriseValue");
            }
            throw e;
        }
        try {
            FfiConverterOptionalString.checkType(experimentConfig)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("experimentConfig");
            }
            throw e;
        }
        /**
         * The name of the parameter in the url.
         * @type {string}
         */
        this.name = name;
        /**
         * The parameter value, this may be a static value, or additionally contain
         * a parameter replacement, e.g. `{inputEncoding}`. For the partner code
         * parameter, this field should be `{partnerCode}`.
         * @type {?string}
         */
        this.value = value;
        /**
         * Same as value but only used if Services.polices.isEnterprise is true. Overrides other parameters of the same name.
         * @type {?string}
         */
        this.enterpriseValue = enterpriseValue;
        /**
         * The value for the parameter will be derived from the equivalent experiment
         * configuration value.
         * Only desktop uses this currently.
         * @type {?string}
         */
        this.experimentConfig = experimentConfig;
    }

    equals(other) {
        return (
            this.name == other.name
            && this.value == other.value
            && this.enterpriseValue == other.enterpriseValue
            && this.experimentConfig == other.experimentConfig
        )
    }
}

// Export the FFIConverter object to make external types work.
export class FfiConverterTypeSearchUrlParam extends FfiConverterArrayBuffer {
    static read(dataStream) {
        return new SearchUrlParam({
            name: FfiConverterString.read(dataStream),
            value: FfiConverterOptionalString.read(dataStream),
            enterpriseValue: FfiConverterOptionalString.read(dataStream),
            experimentConfig: FfiConverterOptionalString.read(dataStream),
        });
    }
    static write(dataStream, value) {
        FfiConverterString.write(dataStream, value.name);
        FfiConverterOptionalString.write(dataStream, value.value);
        FfiConverterOptionalString.write(dataStream, value.enterpriseValue);
        FfiConverterOptionalString.write(dataStream, value.experimentConfig);
    }

    static computeSize(value) {
        let totalSize = 0;
        totalSize += FfiConverterString.computeSize(value.name);
        totalSize += FfiConverterOptionalString.computeSize(value.value);
        totalSize += FfiConverterOptionalString.computeSize(value.enterpriseValue);
        totalSize += FfiConverterOptionalString.computeSize(value.experimentConfig);
        return totalSize
    }

    static checkType(value) {
        super.checkType(value);
        if (!(value instanceof SearchUrlParam)) {
            throw new UniFFITypeError(`Expected 'SearchUrlParam', found '${typeof value}'`);
        }
        try {
            FfiConverterString.checkType(value.name);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".name");
            }
            throw e;
        }
        try {
            FfiConverterOptionalString.checkType(value.value);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".value");
            }
            throw e;
        }
        try {
            FfiConverterOptionalString.checkType(value.enterpriseValue);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".enterpriseValue");
            }
            throw e;
        }
        try {
            FfiConverterOptionalString.checkType(value.experimentConfig);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".experimentConfig");
            }
            throw e;
        }
    }
}
// Export the FFIConverter object to make external types work.
export class FfiConverterSequenceTypeSearchUrlParam extends FfiConverterArrayBuffer {
    static read(dataStream) {
        const len = dataStream.readInt32();
        const arr = [];
        for (let i = 0; i < len; i++) {
            arr.push(FfiConverterTypeSearchUrlParam.read(dataStream));
        }
        return arr;
    }

    static write(dataStream, value) {
        dataStream.writeInt32(value.length);
        value.forEach((innerValue) => {
            FfiConverterTypeSearchUrlParam.write(dataStream, innerValue);
        })
    }

    static computeSize(value) {
        // The size of the length
        let size = 4;
        for (const innerValue of value) {
            size += FfiConverterTypeSearchUrlParam.computeSize(innerValue);
        }
        return size;
    }

    static checkType(value) {
        if (!Array.isArray(value)) {
            throw new UniFFITypeError(`${value} is not an array`);
        }
        value.forEach((innerValue, idx) => {
            try {
                FfiConverterTypeSearchUrlParam.checkType(innerValue);
            } catch (e) {
                if (e instanceof UniFFITypeError) {
                    e.addItemDescriptionPart(`[${idx}]`);
                }
                throw e;
            }
        })
    }
}
// Export the FFIConverter object to make external types work.
export class FfiConverterOptionalSequenceTypeSearchUrlParam extends FfiConverterArrayBuffer {
    static checkType(value) {
        if (value !== undefined && value !== null) {
            FfiConverterSequenceTypeSearchUrlParam.checkType(value)
        }
    }

    static read(dataStream) {
        const code = dataStream.readUint8(0);
        switch (code) {
            case 0:
                return null
            case 1:
                return FfiConverterSequenceTypeSearchUrlParam.read(dataStream)
            default:
                throw new UniFFIError(`Unexpected code: ${code}`);
        }
    }

    static write(dataStream, value) {
        if (value === null || value === undefined) {
            dataStream.writeUint8(0);
            return;
        }
        dataStream.writeUint8(1);
        FfiConverterSequenceTypeSearchUrlParam.write(dataStream, value)
    }

    static computeSize(value) {
        if (value === null || value === undefined) {
            return 1;
        }
        return 1 + FfiConverterSequenceTypeSearchUrlParam.computeSize(value)
    }
}
// Export the FFIConverter object to make external types work.
export class FfiConverterMapStringString extends FfiConverterArrayBuffer {
    static read(dataStream) {
        const len = dataStream.readInt32();
        const map = new Map();
        for (let i = 0; i < len; i++) {
            const key = FfiConverterString.read(dataStream);
            const value = FfiConverterString.read(dataStream);
            map.set(key, value);
        }

        return map;
    }

     static write(dataStream, map) {
        dataStream.writeInt32(map.size);
        for (const [key, value] of map) {
            FfiConverterString.write(dataStream, key);
            FfiConverterString.write(dataStream, value);
        }
    }

    static computeSize(map) {
        // The size of the length
        let size = 4;
        for (const [key, value] of map) {
            size += FfiConverterString.computeSize(key);
            size += FfiConverterString.computeSize(value);
        }
        return size;
    }

    static checkType(map) {
        for (const [key, value] of map) {
            try {
                FfiConverterString.checkType(key);
            } catch (e) {
                if (e instanceof UniFFITypeError) {
                    e.addItemDescriptionPart("(key)");
                }
                throw e;
            }

            try {
                FfiConverterString.checkType(value);
            } catch (e) {
                if (e instanceof UniFFITypeError) {
                    e.addItemDescriptionPart(`[${key}]`);
                }
                throw e;
            }
        }
    }
}
// Export the FFIConverter object to make external types work.
export class FfiConverterOptionalMapStringString extends FfiConverterArrayBuffer {
    static checkType(value) {
        if (value !== undefined && value !== null) {
            FfiConverterMapStringString.checkType(value)
        }
    }

    static read(dataStream) {
        const code = dataStream.readUint8(0);
        switch (code) {
            case 0:
                return null
            case 1:
                return FfiConverterMapStringString.read(dataStream)
            default:
                throw new UniFFIError(`Unexpected code: ${code}`);
        }
    }

    static write(dataStream, value) {
        if (value === null || value === undefined) {
            dataStream.writeUint8(0);
            return;
        }
        dataStream.writeUint8(1);
        FfiConverterMapStringString.write(dataStream, value)
    }

    static computeSize(value) {
        if (value === null || value === undefined) {
            return 1;
        }
        return 1 + FfiConverterMapStringString.computeSize(value)
    }
}


// Export the FFIConverter object to make external types work.
export class FfiConverterSequenceString extends FfiConverterArrayBuffer {
    static read(dataStream) {
        const len = dataStream.readInt32();
        const arr = [];
        for (let i = 0; i < len; i++) {
            arr.push(FfiConverterString.read(dataStream));
        }
        return arr;
    }

    static write(dataStream, value) {
        dataStream.writeInt32(value.length);
        value.forEach((innerValue) => {
            FfiConverterString.write(dataStream, innerValue);
        })
    }

    static computeSize(value) {
        // The size of the length
        let size = 4;
        for (const innerValue of value) {
            size += FfiConverterString.computeSize(innerValue);
        }
        return size;
    }

    static checkType(value) {
        if (!Array.isArray(value)) {
            throw new UniFFITypeError(`${value} is not an array`);
        }
        value.forEach((innerValue, idx) => {
            try {
                FfiConverterString.checkType(innerValue);
            } catch (e) {
                if (e instanceof UniFFITypeError) {
                    e.addItemDescriptionPart(`[${idx}]`);
                }
                throw e;
            }
        })
    }
}
// Export the FFIConverter object to make external types work.
export class FfiConverterOptionalSequenceString extends FfiConverterArrayBuffer {
    static checkType(value) {
        if (value !== undefined && value !== null) {
            FfiConverterSequenceString.checkType(value)
        }
    }

    static read(dataStream) {
        const code = dataStream.readUint8(0);
        switch (code) {
            case 0:
                return null
            case 1:
                return FfiConverterSequenceString.read(dataStream)
            default:
                throw new UniFFIError(`Unexpected code: ${code}`);
        }
    }

    static write(dataStream, value) {
        if (value === null || value === undefined) {
            dataStream.writeUint8(0);
            return;
        }
        dataStream.writeUint8(1);
        FfiConverterSequenceString.write(dataStream, value)
    }

    static computeSize(value) {
        if (value === null || value === undefined) {
            return 1;
        }
        return 1 + FfiConverterSequenceString.computeSize(value)
    }
}
/**
 * Defines an individual search engine URL. This is defined separately to
 * `types::SearchEngineUrl` as various fields may be optional in the supplied
 * configuration.
 */
export class JsonEngineUrl {
    constructor(
        {
            base, 
            method, 
            params, 
            searchTermParamName, 
            displayNameMap, 
            isNewUntil, 
            excludePartnerCodeFromTelemetry, 
            acceptedContentTypes
        } = {
            base: undefined, 
            method: undefined, 
            params: undefined, 
            searchTermParamName: undefined, 
            displayNameMap: undefined, 
            isNewUntil: undefined, 
            excludePartnerCodeFromTelemetry: undefined, 
            acceptedContentTypes: undefined
        }
    ) {
        try {
            FfiConverterOptionalString.checkType(base)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("base");
            }
            throw e;
        }
        try {
            FfiConverterOptionalTypeJSONEngineMethod.checkType(method)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("method");
            }
            throw e;
        }
        try {
            FfiConverterOptionalSequenceTypeSearchUrlParam.checkType(params)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("params");
            }
            throw e;
        }
        try {
            FfiConverterOptionalString.checkType(searchTermParamName)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("searchTermParamName");
            }
            throw e;
        }
        try {
            FfiConverterOptionalMapStringString.checkType(displayNameMap)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("displayNameMap");
            }
            throw e;
        }
        try {
            FfiConverterOptionalString.checkType(isNewUntil)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("isNewUntil");
            }
            throw e;
        }
        try {
            FfiConverterBoolean.checkType(excludePartnerCodeFromTelemetry)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("excludePartnerCodeFromTelemetry");
            }
            throw e;
        }
        try {
            FfiConverterOptionalSequenceString.checkType(acceptedContentTypes)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("acceptedContentTypes");
            }
            throw e;
        }
        /**
         * The PrePath and FilePath of the URL. May include variables for engines
         * which have a variable FilePath, e.g. `{searchTerms}` for when a search
         * term is within the path of the url.
         * @type {?string}
         */
        this.base = base;
        /**
         * The HTTP method to use to send the request (`GET` or `POST`).
         * If the engine definition has not specified the method, it defaults to GET.
         * @type {?JsonEngineMethod[keyof JsonEngineMethod]}
         */
        this.method = method;
        /**
         * The parameters for this URL.
         * @type {?Array.<SearchUrlParam>}
         */
        this.params = params;
        /**
         * The name of the query parameter for the search term. Automatically
         * appended to the end of the query. This may be skipped if `{searchTerms}`
         * is included in the base.
         * @type {?string}
         */
        this.searchTermParamName = searchTermParamName;
        /**
         * A map from locale codes to display names of the URL. This is useful if
         * the URL corresponds to a brand name distinct from the engine's brand
         * name. Since brand names can be localized, this is a map rather than a
         * URL. The client will fall back to the special locale code "default" when
         * its locale is not present in the map.
         * @type {?object}
         */
        this.displayNameMap = displayNameMap;
        /**
         * Indicates the date until which the URL is considered new
         * (format: YYYY-MM-DD).
         * @type {?string}
         */
        this.isNewUntil = isNewUntil;
        /**
         * Whether the engine's partner code should be excluded from telemetry when
         * this URL is visited.
         * @type {boolean}
         */
        this.excludePartnerCodeFromTelemetry = excludePartnerCodeFromTelemetry;
        /**
         * If this URL performs searches only for certain MIME types, they should
         * be listed here. If this value is `None`, then it's assumed the content
         * type is irrelevant. This field is intended to be used for URLs like
         * visual search, which might support certain image types and not others.
         * Consumers can use it to determine whether search UI corresponding to the
         * URL should be shown to the user in a given context.
         * @type {?Array.<string>}
         */
        this.acceptedContentTypes = acceptedContentTypes;
    }

    equals(other) {
        return (
            this.base == other.base
            && this.method == other.method
            && this.params == other.params
            && this.searchTermParamName == other.searchTermParamName
            && this.displayNameMap == other.displayNameMap
            && this.isNewUntil == other.isNewUntil
            && this.excludePartnerCodeFromTelemetry == other.excludePartnerCodeFromTelemetry
            && this.acceptedContentTypes == other.acceptedContentTypes
        )
    }
}

// Export the FFIConverter object to make external types work.
export class FfiConverterTypeJSONEngineUrl extends FfiConverterArrayBuffer {
    static read(dataStream) {
        return new JsonEngineUrl({
            base: FfiConverterOptionalString.read(dataStream),
            method: FfiConverterOptionalTypeJSONEngineMethod.read(dataStream),
            params: FfiConverterOptionalSequenceTypeSearchUrlParam.read(dataStream),
            searchTermParamName: FfiConverterOptionalString.read(dataStream),
            displayNameMap: FfiConverterOptionalMapStringString.read(dataStream),
            isNewUntil: FfiConverterOptionalString.read(dataStream),
            excludePartnerCodeFromTelemetry: FfiConverterBoolean.read(dataStream),
            acceptedContentTypes: FfiConverterOptionalSequenceString.read(dataStream),
        });
    }
    static write(dataStream, value) {
        FfiConverterOptionalString.write(dataStream, value.base);
        FfiConverterOptionalTypeJSONEngineMethod.write(dataStream, value.method);
        FfiConverterOptionalSequenceTypeSearchUrlParam.write(dataStream, value.params);
        FfiConverterOptionalString.write(dataStream, value.searchTermParamName);
        FfiConverterOptionalMapStringString.write(dataStream, value.displayNameMap);
        FfiConverterOptionalString.write(dataStream, value.isNewUntil);
        FfiConverterBoolean.write(dataStream, value.excludePartnerCodeFromTelemetry);
        FfiConverterOptionalSequenceString.write(dataStream, value.acceptedContentTypes);
    }

    static computeSize(value) {
        let totalSize = 0;
        totalSize += FfiConverterOptionalString.computeSize(value.base);
        totalSize += FfiConverterOptionalTypeJSONEngineMethod.computeSize(value.method);
        totalSize += FfiConverterOptionalSequenceTypeSearchUrlParam.computeSize(value.params);
        totalSize += FfiConverterOptionalString.computeSize(value.searchTermParamName);
        totalSize += FfiConverterOptionalMapStringString.computeSize(value.displayNameMap);
        totalSize += FfiConverterOptionalString.computeSize(value.isNewUntil);
        totalSize += FfiConverterBoolean.computeSize(value.excludePartnerCodeFromTelemetry);
        totalSize += FfiConverterOptionalSequenceString.computeSize(value.acceptedContentTypes);
        return totalSize
    }

    static checkType(value) {
        super.checkType(value);
        if (!(value instanceof JsonEngineUrl)) {
            throw new UniFFITypeError(`Expected 'JsonEngineUrl', found '${typeof value}'`);
        }
        try {
            FfiConverterOptionalString.checkType(value.base);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".base");
            }
            throw e;
        }
        try {
            FfiConverterOptionalTypeJSONEngineMethod.checkType(value.method);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".method");
            }
            throw e;
        }
        try {
            FfiConverterOptionalSequenceTypeSearchUrlParam.checkType(value.params);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".params");
            }
            throw e;
        }
        try {
            FfiConverterOptionalString.checkType(value.searchTermParamName);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".searchTermParamName");
            }
            throw e;
        }
        try {
            FfiConverterOptionalMapStringString.checkType(value.displayNameMap);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".displayNameMap");
            }
            throw e;
        }
        try {
            FfiConverterOptionalString.checkType(value.isNewUntil);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".isNewUntil");
            }
            throw e;
        }
        try {
            FfiConverterBoolean.checkType(value.excludePartnerCodeFromTelemetry);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".excludePartnerCodeFromTelemetry");
            }
            throw e;
        }
        try {
            FfiConverterOptionalSequenceString.checkType(value.acceptedContentTypes);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".acceptedContentTypes");
            }
            throw e;
        }
    }
}
// Export the FFIConverter object to make external types work.
export class FfiConverterOptionalTypeJSONEngineUrl extends FfiConverterArrayBuffer {
    static checkType(value) {
        if (value !== undefined && value !== null) {
            FfiConverterTypeJSONEngineUrl.checkType(value)
        }
    }

    static read(dataStream) {
        const code = dataStream.readUint8(0);
        switch (code) {
            case 0:
                return null
            case 1:
                return FfiConverterTypeJSONEngineUrl.read(dataStream)
            default:
                throw new UniFFIError(`Unexpected code: ${code}`);
        }
    }

    static write(dataStream, value) {
        if (value === null || value === undefined) {
            dataStream.writeUint8(0);
            return;
        }
        dataStream.writeUint8(1);
        FfiConverterTypeJSONEngineUrl.write(dataStream, value)
    }

    static computeSize(value) {
        if (value === null || value === undefined) {
            return 1;
        }
        return 1 + FfiConverterTypeJSONEngineUrl.computeSize(value)
    }
}
/**
 * Reflects `types::SearchEngineUrls`, but using `EngineUrl`.
 */
export class JsonEngineUrls {
    constructor(
        {
            search, 
            suggestions, 
            trending, 
            searchForm, 
            visualSearch
        } = {
            search: undefined, 
            suggestions: undefined, 
            trending: undefined, 
            searchForm: undefined, 
            visualSearch: undefined
        }
    ) {
        try {
            FfiConverterOptionalTypeJSONEngineUrl.checkType(search)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("search");
            }
            throw e;
        }
        try {
            FfiConverterOptionalTypeJSONEngineUrl.checkType(suggestions)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("suggestions");
            }
            throw e;
        }
        try {
            FfiConverterOptionalTypeJSONEngineUrl.checkType(trending)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("trending");
            }
            throw e;
        }
        try {
            FfiConverterOptionalTypeJSONEngineUrl.checkType(searchForm)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("searchForm");
            }
            throw e;
        }
        try {
            FfiConverterOptionalTypeJSONEngineUrl.checkType(visualSearch)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("visualSearch");
            }
            throw e;
        }
        /**
         * The URL to use for searches.
         * @type {?JsonEngineUrl}
         */
        this.search = search;
        /**
         * The URL to use for suggestions.
         * @type {?JsonEngineUrl}
         */
        this.suggestions = suggestions;
        /**
         * The URL to use for trending suggestions.
         * @type {?JsonEngineUrl}
         */
        this.trending = trending;
        /**
         * The URL of the search engine homepage.
         * @type {?JsonEngineUrl}
         */
        this.searchForm = searchForm;
        /**
         * The URL to use for visual searches.
         * @type {?JsonEngineUrl}
         */
        this.visualSearch = visualSearch;
    }

    equals(other) {
        return (
            this.search == other.search
            && this.suggestions == other.suggestions
            && this.trending == other.trending
            && this.searchForm == other.searchForm
            && this.visualSearch == other.visualSearch
        )
    }
}

// Export the FFIConverter object to make external types work.
export class FfiConverterTypeJSONEngineUrls extends FfiConverterArrayBuffer {
    static read(dataStream) {
        return new JsonEngineUrls({
            search: FfiConverterOptionalTypeJSONEngineUrl.read(dataStream),
            suggestions: FfiConverterOptionalTypeJSONEngineUrl.read(dataStream),
            trending: FfiConverterOptionalTypeJSONEngineUrl.read(dataStream),
            searchForm: FfiConverterOptionalTypeJSONEngineUrl.read(dataStream),
            visualSearch: FfiConverterOptionalTypeJSONEngineUrl.read(dataStream),
        });
    }
    static write(dataStream, value) {
        FfiConverterOptionalTypeJSONEngineUrl.write(dataStream, value.search);
        FfiConverterOptionalTypeJSONEngineUrl.write(dataStream, value.suggestions);
        FfiConverterOptionalTypeJSONEngineUrl.write(dataStream, value.trending);
        FfiConverterOptionalTypeJSONEngineUrl.write(dataStream, value.searchForm);
        FfiConverterOptionalTypeJSONEngineUrl.write(dataStream, value.visualSearch);
    }

    static computeSize(value) {
        let totalSize = 0;
        totalSize += FfiConverterOptionalTypeJSONEngineUrl.computeSize(value.search);
        totalSize += FfiConverterOptionalTypeJSONEngineUrl.computeSize(value.suggestions);
        totalSize += FfiConverterOptionalTypeJSONEngineUrl.computeSize(value.trending);
        totalSize += FfiConverterOptionalTypeJSONEngineUrl.computeSize(value.searchForm);
        totalSize += FfiConverterOptionalTypeJSONEngineUrl.computeSize(value.visualSearch);
        return totalSize
    }

    static checkType(value) {
        super.checkType(value);
        if (!(value instanceof JsonEngineUrls)) {
            throw new UniFFITypeError(`Expected 'JsonEngineUrls', found '${typeof value}'`);
        }
        try {
            FfiConverterOptionalTypeJSONEngineUrl.checkType(value.search);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".search");
            }
            throw e;
        }
        try {
            FfiConverterOptionalTypeJSONEngineUrl.checkType(value.suggestions);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".suggestions");
            }
            throw e;
        }
        try {
            FfiConverterOptionalTypeJSONEngineUrl.checkType(value.trending);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".trending");
            }
            throw e;
        }
        try {
            FfiConverterOptionalTypeJSONEngineUrl.checkType(value.searchForm);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".searchForm");
            }
            throw e;
        }
        try {
            FfiConverterOptionalTypeJSONEngineUrl.checkType(value.visualSearch);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".visualSearch");
            }
            throw e;
        }
    }
}

/**
 * The list of acceptable classifications for a search engine.
 */
export const SearchEngineClassification = Object.freeze({
    /**
     * GENERAL
     */
    GENERAL: 2,
    /**
     * UNKNOWN
     */
    UNKNOWN: 1,
});

// Export the FFIConverter object to make external types work.
export class FfiConverterTypeSearchEngineClassification extends FfiConverterArrayBuffer {
    static #validValues = Object.values(SearchEngineClassification)

    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
            case 2:
                return SearchEngineClassification.UNKNOWN
            default:
                throw new UniFFITypeError("Unknown SearchEngineClassification variant");
        }
    }

    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;
        }
        if (value === SearchEngineClassification.UNKNOWN) {
            dataStream.writeInt32(2);
            return;
        }
        throw new UniFFITypeError("Unknown SearchEngineClassification variant");
    }

    static computeSize(value) {
        return 4;
    }

    static checkType(value) {
      // Check that the value is a valid enum variant
      if (!this.#validValues.includes(value)) {
          throw new UniFFITypeError(`${value} is not a valid value for SearchEngineClassification`);
      }
    }
}
/**
 * Defines an individual search engine URL.
 */
export class SearchEngineUrl {
    constructor(
        {
            base, 
            method, 
            params, 
            searchTermParamName, 
            displayName= null, 
            isNewUntil= null, 
            excludePartnerCodeFromTelemetry= false, 
            acceptedContentTypes= null
        } = {
            base: undefined, 
            method: undefined, 
            params: undefined, 
            searchTermParamName: undefined, 
            displayName: undefined, 
            isNewUntil: undefined, 
            excludePartnerCodeFromTelemetry: undefined, 
            acceptedContentTypes: undefined
        }
    ) {
        try {
            FfiConverterString.checkType(base)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("base");
            }
            throw e;
        }
        try {
            FfiConverterString.checkType(method)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("method");
            }
            throw e;
        }
        try {
            FfiConverterSequenceTypeSearchUrlParam.checkType(params)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("params");
            }
            throw e;
        }
        try {
            FfiConverterOptionalString.checkType(searchTermParamName)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("searchTermParamName");
            }
            throw e;
        }
        try {
            FfiConverterOptionalString.checkType(displayName)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("displayName");
            }
            throw e;
        }
        try {
            FfiConverterOptionalString.checkType(isNewUntil)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("isNewUntil");
            }
            throw e;
        }
        try {
            FfiConverterBoolean.checkType(excludePartnerCodeFromTelemetry)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("excludePartnerCodeFromTelemetry");
            }
            throw e;
        }
        try {
            FfiConverterOptionalSequenceString.checkType(acceptedContentTypes)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("acceptedContentTypes");
            }
            throw e;
        }
        /**
         * The PrePath and FilePath of the URL. May include variables for engines
         * which have a variable FilePath, e.g. `{searchTerms}` for when a search
         * term is within the path of the url.
         * @type {string}
         */
        this.base = base;
        /**
         * The HTTP method to use to send the request (`GET` or `POST`).
         * If the engine definition has not specified the method, it defaults to GET.
         * @type {string}
         */
        this.method = method;
        /**
         * The parameters for this URL.
         * @type {Array.<SearchUrlParam>}
         */
        this.params = params;
        /**
         * The name of the query parameter for the search term. Automatically
         * appended to the end of the query. This may be skipped if `{searchTerms}`
         * is included in the base.
         * @type {?string}
         */
        this.searchTermParamName = searchTermParamName;
        /**
         * The display name of the URL, if any. This is useful if the URL
         * corresponds to a brand name distinct from the engine's brand name.
         * @type {?string}
         */
        this.displayName = displayName;
        /**
         * Indicates the date until which the URL is considered new
         * (format: YYYY-MM-DD).
         * @type {?string}
         */
        this.isNewUntil = isNewUntil;
        /**
         * Whether the engine's partner code should be excluded from telemetry when
         * this URL is visited.
         * @type {boolean}
         */
        this.excludePartnerCodeFromTelemetry = excludePartnerCodeFromTelemetry;
        /**
         * If this URL performs searches only for certain MIME types, they should
         * be listed here. If `None`, it's assumed the content type is text or not
         * relevant. This field is intended to be used for URLs like visual search,
         * which might support certain image types and not others. Consumers can
         * use it to determine whether search UI corresponding to the URL should be
         * shown to the user in a given context.
         * @type {?Array.<string>}
         */
        this.acceptedContentTypes = acceptedContentTypes;
    }

    equals(other) {
        return (
            this.base == other.base
            && this.method == other.method
            && this.params == other.params
            && this.searchTermParamName == other.searchTermParamName
            && this.displayName == other.displayName
            && this.isNewUntil == other.isNewUntil
            && this.excludePartnerCodeFromTelemetry == other.excludePartnerCodeFromTelemetry
            && this.acceptedContentTypes == other.acceptedContentTypes
        )
    }
}

// Export the FFIConverter object to make external types work.
export class FfiConverterTypeSearchEngineUrl extends FfiConverterArrayBuffer {
    static read(dataStream) {
        return new SearchEngineUrl({
            base: FfiConverterString.read(dataStream),
            method: FfiConverterString.read(dataStream),
            params: FfiConverterSequenceTypeSearchUrlParam.read(dataStream),
            searchTermParamName: FfiConverterOptionalString.read(dataStream),
            displayName: FfiConverterOptionalString.read(dataStream),
            isNewUntil: FfiConverterOptionalString.read(dataStream),
            excludePartnerCodeFromTelemetry: FfiConverterBoolean.read(dataStream),
            acceptedContentTypes: FfiConverterOptionalSequenceString.read(dataStream),
        });
    }
    static write(dataStream, value) {
        FfiConverterString.write(dataStream, value.base);
        FfiConverterString.write(dataStream, value.method);
        FfiConverterSequenceTypeSearchUrlParam.write(dataStream, value.params);
        FfiConverterOptionalString.write(dataStream, value.searchTermParamName);
        FfiConverterOptionalString.write(dataStream, value.displayName);
        FfiConverterOptionalString.write(dataStream, value.isNewUntil);
        FfiConverterBoolean.write(dataStream, value.excludePartnerCodeFromTelemetry);
        FfiConverterOptionalSequenceString.write(dataStream, value.acceptedContentTypes);
    }

    static computeSize(value) {
        let totalSize = 0;
        totalSize += FfiConverterString.computeSize(value.base);
        totalSize += FfiConverterString.computeSize(value.method);
        totalSize += FfiConverterSequenceTypeSearchUrlParam.computeSize(value.params);
        totalSize += FfiConverterOptionalString.computeSize(value.searchTermParamName);
        totalSize += FfiConverterOptionalString.computeSize(value.displayName);
        totalSize += FfiConverterOptionalString.computeSize(value.isNewUntil);
        totalSize += FfiConverterBoolean.computeSize(value.excludePartnerCodeFromTelemetry);
        totalSize += FfiConverterOptionalSequenceString.computeSize(value.acceptedContentTypes);
        return totalSize
    }

    static checkType(value) {
        super.checkType(value);
        if (!(value instanceof SearchEngineUrl)) {
            throw new UniFFITypeError(`Expected 'SearchEngineUrl', found '${typeof value}'`);
        }
        try {
            FfiConverterString.checkType(value.base);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".base");
            }
            throw e;
        }
        try {
            FfiConverterString.checkType(value.method);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".method");
            }
            throw e;
        }
        try {
            FfiConverterSequenceTypeSearchUrlParam.checkType(value.params);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".params");
            }
            throw e;
        }
        try {
            FfiConverterOptionalString.checkType(value.searchTermParamName);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".searchTermParamName");
            }
            throw e;
        }
        try {
            FfiConverterOptionalString.checkType(value.displayName);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".displayName");
            }
            throw e;
        }
        try {
            FfiConverterOptionalString.checkType(value.isNewUntil);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".isNewUntil");
            }
            throw e;
        }
        try {
            FfiConverterBoolean.checkType(value.excludePartnerCodeFromTelemetry);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".excludePartnerCodeFromTelemetry");
            }
            throw e;
        }
        try {
            FfiConverterOptionalSequenceString.checkType(value.acceptedContentTypes);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".acceptedContentTypes");
            }
            throw e;
        }
    }
}
// Export the FFIConverter object to make external types work.
export class FfiConverterOptionalTypeSearchEngineUrl extends FfiConverterArrayBuffer {
    static checkType(value) {
        if (value !== undefined && value !== null) {
            FfiConverterTypeSearchEngineUrl.checkType(value)
        }
    }

    static read(dataStream) {
        const code = dataStream.readUint8(0);
        switch (code) {
            case 0:
                return null
            case 1:
                return FfiConverterTypeSearchEngineUrl.read(dataStream)
            default:
                throw new UniFFIError(`Unexpected code: ${code}`);
        }
    }

    static write(dataStream, value) {
        if (value === null || value === undefined) {
            dataStream.writeUint8(0);
            return;
        }
        dataStream.writeUint8(1);
        FfiConverterTypeSearchEngineUrl.write(dataStream, value)
    }

    static computeSize(value) {
        if (value === null || value === undefined) {
            return 1;
        }
        return 1 + FfiConverterTypeSearchEngineUrl.computeSize(value)
    }
}
/**
 * The URLs associated with the search engine.
 */
export class SearchEngineUrls {
    constructor(
        {
            search, 
            suggestions, 
            trending, 
            searchForm, 
            visualSearch
        } = {
            search: undefined, 
            suggestions: undefined, 
            trending: undefined, 
            searchForm: undefined, 
            visualSearch: undefined
        }
    ) {
        try {
            FfiConverterTypeSearchEngineUrl.checkType(search)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("search");
            }
            throw e;
        }
        try {
            FfiConverterOptionalTypeSearchEngineUrl.checkType(suggestions)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("suggestions");
            }
            throw e;
        }
        try {
            FfiConverterOptionalTypeSearchEngineUrl.checkType(trending)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("trending");
            }
            throw e;
        }
        try {
            FfiConverterOptionalTypeSearchEngineUrl.checkType(searchForm)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("searchForm");
            }
            throw e;
        }
        try {
            FfiConverterOptionalTypeSearchEngineUrl.checkType(visualSearch)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("visualSearch");
            }
            throw e;
        }
        /**
         * The URL to use for searches.
         * @type {SearchEngineUrl}
         */
        this.search = search;
        /**
         * The URL to use for suggestions.
         * @type {?SearchEngineUrl}
         */
        this.suggestions = suggestions;
        /**
         * The URL to use for trending suggestions.
         * @type {?SearchEngineUrl}
         */
        this.trending = trending;
        /**
         * The URL of the search engine homepage.
         * @type {?SearchEngineUrl}
         */
        this.searchForm = searchForm;
        /**
         * The URL to use for visual searches.
         * @type {?SearchEngineUrl}
         */
        this.visualSearch = visualSearch;
    }

    equals(other) {
        return (
            this.search.equals(other.search)
            && this.suggestions == other.suggestions
            && this.trending == other.trending
            && this.searchForm == other.searchForm
            && this.visualSearch == other.visualSearch
        )
    }
}

// Export the FFIConverter object to make external types work.
export class FfiConverterTypeSearchEngineUrls extends FfiConverterArrayBuffer {
    static read(dataStream) {
        return new SearchEngineUrls({
            search: FfiConverterTypeSearchEngineUrl.read(dataStream),
            suggestions: FfiConverterOptionalTypeSearchEngineUrl.read(dataStream),
            trending: FfiConverterOptionalTypeSearchEngineUrl.read(dataStream),
            searchForm: FfiConverterOptionalTypeSearchEngineUrl.read(dataStream),
            visualSearch: FfiConverterOptionalTypeSearchEngineUrl.read(dataStream),
        });
    }
    static write(dataStream, value) {
        FfiConverterTypeSearchEngineUrl.write(dataStream, value.search);
        FfiConverterOptionalTypeSearchEngineUrl.write(dataStream, value.suggestions);
        FfiConverterOptionalTypeSearchEngineUrl.write(dataStream, value.trending);
        FfiConverterOptionalTypeSearchEngineUrl.write(dataStream, value.searchForm);
        FfiConverterOptionalTypeSearchEngineUrl.write(dataStream, value.visualSearch);
    }

    static computeSize(value) {
        let totalSize = 0;
        totalSize += FfiConverterTypeSearchEngineUrl.computeSize(value.search);
        totalSize += FfiConverterOptionalTypeSearchEngineUrl.computeSize(value.suggestions);
        totalSize += FfiConverterOptionalTypeSearchEngineUrl.computeSize(value.trending);
        totalSize += FfiConverterOptionalTypeSearchEngineUrl.computeSize(value.searchForm);
        totalSize += FfiConverterOptionalTypeSearchEngineUrl.computeSize(value.visualSearch);
        return totalSize
    }

    static checkType(value) {
        super.checkType(value);
        if (!(value instanceof SearchEngineUrls)) {
            throw new UniFFITypeError(`Expected 'SearchEngineUrls', found '${typeof value}'`);
        }
        try {
            FfiConverterTypeSearchEngineUrl.checkType(value.search);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".search");
            }
            throw e;
        }
        try {
            FfiConverterOptionalTypeSearchEngineUrl.checkType(value.suggestions);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".suggestions");
            }
            throw e;
        }
        try {
            FfiConverterOptionalTypeSearchEngineUrl.checkType(value.trending);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".trending");
            }
            throw e;
        }
        try {
            FfiConverterOptionalTypeSearchEngineUrl.checkType(value.searchForm);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".searchForm");
            }
            throw e;
        }
        try {
            FfiConverterOptionalTypeSearchEngineUrl.checkType(value.visualSearch);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".visualSearch");
            }
            throw e;
        }
    }
}


// Export the FFIConverter object to make external types work.
export class FfiConverterOptionalUInt32 extends FfiConverterArrayBuffer {
    static checkType(value) {
        if (value !== undefined && value !== null) {
            FfiConverterUInt32.checkType(value)
        }
    }

    static read(dataStream) {
        const code = dataStream.readUint8(0);
        switch (code) {
            case 0:
                return null
            case 1:
                return FfiConverterUInt32.read(dataStream)
            default:
                throw new UniFFIError(`Unexpected code: ${code}`);
        }
    }

    static write(dataStream, value) {
        if (value === null || value === undefined) {
            dataStream.writeUint8(0);
            return;
        }
        dataStream.writeUint8(1);
        FfiConverterUInt32.write(dataStream, value)
    }

    static computeSize(value) {
        if (value === null || value === undefined) {
            return 1;
        }
        return 1 + FfiConverterUInt32.computeSize(value)
    }
}
/**
 * A definition for an individual search engine to be presented to the user.
 */
export class SearchEngineDefinition {
    constructor(
        {
            aliases, 
            charset, 
            classification, 
            identifier, 
            isNewUntil, 
            name, 
            optional, 
            partnerCode, 
            telemetrySuffix, 
            urls, 
            orderHint, 
            clickUrl
        } = {
            aliases: undefined, 
            charset: undefined, 
            classification: undefined, 
            identifier: undefined, 
            isNewUntil: undefined, 
            name: undefined, 
            optional: undefined, 
            partnerCode: undefined, 
            telemetrySuffix: undefined, 
            urls: undefined, 
            orderHint: undefined, 
            clickUrl: undefined
        }
    ) {
        try {
            FfiConverterSequenceString.checkType(aliases)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("aliases");
            }
            throw e;
        }
        try {
            FfiConverterString.checkType(charset)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("charset");
            }
            throw e;
        }
        try {
            FfiConverterTypeSearchEngineClassification.checkType(classification)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("classification");
            }
            throw e;
        }
        try {
            FfiConverterString.checkType(identifier)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("identifier");
            }
            throw e;
        }
        try {
            FfiConverterOptionalString.checkType(isNewUntil)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("isNewUntil");
            }
            throw e;
        }
        try {
            FfiConverterString.checkType(name)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("name");
            }
            throw e;
        }
        try {
            FfiConverterBoolean.checkType(optional)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("optional");
            }
            throw e;
        }
        try {
            FfiConverterString.checkType(partnerCode)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("partnerCode");
            }
            throw e;
        }
        try {
            FfiConverterString.checkType(telemetrySuffix)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("telemetrySuffix");
            }
            throw e;
        }
        try {
            FfiConverterTypeSearchEngineUrls.checkType(urls)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("urls");
            }
            throw e;
        }
        try {
            FfiConverterOptionalUInt32.checkType(orderHint)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("orderHint");
            }
            throw e;
        }
        try {
            FfiConverterOptionalString.checkType(clickUrl)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("clickUrl");
            }
            throw e;
        }
        /**
         * A list of aliases for this engine.
         * @type {Array.<string>}
         */
        this.aliases = aliases;
        /**
         * The character set this engine uses for queries.
         * @type {string}
         */
        this.charset = charset;
        /**
         * The classification of search engine according to the main search types
         * (e.g. general, shopping, travel, dictionary). Currently, only marking as
         * a general search engine is supported.
         * On Android, only general search engines may be selected as "default"
         * search engines.
         * @type {SearchEngineClassification[keyof SearchEngineClassification]}
         */
        this.classification = classification;
        /**
         * The identifier of the search engine. This is used as an internal
         * identifier, e.g. for saving the user's settings for the engine. It is
         * also used to form the base telemetry id and may be extended by telemetrySuffix.
         * @type {string}
         */
        this.identifier = identifier;
        /**
         * Indicates the date until which the engine variant or subvariant is considered new
         * (format: YYYY-MM-DD).
         * @type {?string}
         */
        this.isNewUntil = isNewUntil;
        /**
         * The user visible name of the search engine.
         * @type {string}
         */
        this.name = name;
        /**
         * This search engine is presented as an option that the user may enable.
         * The application should not include these in the default list of the
         * user's engines. If not supported, it should filter them out.
         * @type {boolean}
         */
        this.optional = optional;
        /**
         * The partner code for the engine. This will be inserted into parameters
         * which include `{partnerCode}`. May be the empty string.
         * @type {string}
         */
        this.partnerCode = partnerCode;
        /**
         * Optional suffix that is appended to the search engine identifier
         * following a dash, i.e. `<identifier>-<suffix>`. If it is an empty string
         * no dash should be appended.
         * @type {string}
         */
        this.telemetrySuffix = telemetrySuffix;
        /**
         * The URLs associated with the search engine.
         * @type {SearchEngineUrls}
         */
        this.urls = urls;
        /**
         * A hint to the order that this engine should be in the engine list. This
         * is derived from the `engineOrders` section of the search configuration.
         * The higher the number, the nearer to the front it should be.
         * If the number is not specified, other methods of sorting may be relied
         * upon (e.g. alphabetical).
         * @type {?number}
         */
        this.orderHint = orderHint;
        /**
         * The url used for reporting clicks.
         * @type {?string}
         */
        this.clickUrl = clickUrl;
    }

    equals(other) {
        return (
            this.aliases == other.aliases
            && this.charset == other.charset
            && this.classification == other.classification
            && this.identifier == other.identifier
            && this.isNewUntil == other.isNewUntil
            && this.name == other.name
            && this.optional == other.optional
            && this.partnerCode == other.partnerCode
            && this.telemetrySuffix == other.telemetrySuffix
            && this.urls.equals(other.urls)
            && this.orderHint == other.orderHint
            && this.clickUrl == other.clickUrl
        )
    }
}

// Export the FFIConverter object to make external types work.
export class FfiConverterTypeSearchEngineDefinition extends FfiConverterArrayBuffer {
    static read(dataStream) {
        return new SearchEngineDefinition({
            aliases: FfiConverterSequenceString.read(dataStream),
            charset: FfiConverterString.read(dataStream),
            classification: FfiConverterTypeSearchEngineClassification.read(dataStream),
            identifier: FfiConverterString.read(dataStream),
            isNewUntil: FfiConverterOptionalString.read(dataStream),
            name: FfiConverterString.read(dataStream),
            optional: FfiConverterBoolean.read(dataStream),
            partnerCode: FfiConverterString.read(dataStream),
            telemetrySuffix: FfiConverterString.read(dataStream),
            urls: FfiConverterTypeSearchEngineUrls.read(dataStream),
            orderHint: FfiConverterOptionalUInt32.read(dataStream),
            clickUrl: FfiConverterOptionalString.read(dataStream),
        });
    }
    static write(dataStream, value) {
        FfiConverterSequenceString.write(dataStream, value.aliases);
        FfiConverterString.write(dataStream, value.charset);
        FfiConverterTypeSearchEngineClassification.write(dataStream, value.classification);
        FfiConverterString.write(dataStream, value.identifier);
        FfiConverterOptionalString.write(dataStream, value.isNewUntil);
        FfiConverterString.write(dataStream, value.name);
        FfiConverterBoolean.write(dataStream, value.optional);
        FfiConverterString.write(dataStream, value.partnerCode);
        FfiConverterString.write(dataStream, value.telemetrySuffix);
        FfiConverterTypeSearchEngineUrls.write(dataStream, value.urls);
        FfiConverterOptionalUInt32.write(dataStream, value.orderHint);
        FfiConverterOptionalString.write(dataStream, value.clickUrl);
    }

    static computeSize(value) {
        let totalSize = 0;
        totalSize += FfiConverterSequenceString.computeSize(value.aliases);
        totalSize += FfiConverterString.computeSize(value.charset);
        totalSize += FfiConverterTypeSearchEngineClassification.computeSize(value.classification);
        totalSize += FfiConverterString.computeSize(value.identifier);
        totalSize += FfiConverterOptionalString.computeSize(value.isNewUntil);
        totalSize += FfiConverterString.computeSize(value.name);
        totalSize += FfiConverterBoolean.computeSize(value.optional);
        totalSize += FfiConverterString.computeSize(value.partnerCode);
        totalSize += FfiConverterString.computeSize(value.telemetrySuffix);
        totalSize += FfiConverterTypeSearchEngineUrls.computeSize(value.urls);
        totalSize += FfiConverterOptionalUInt32.computeSize(value.orderHint);
        totalSize += FfiConverterOptionalString.computeSize(value.clickUrl);
        return totalSize
    }

    static checkType(value) {
        super.checkType(value);
        if (!(value instanceof SearchEngineDefinition)) {
            throw new UniFFITypeError(`Expected 'SearchEngineDefinition', found '${typeof value}'`);
        }
        try {
            FfiConverterSequenceString.checkType(value.aliases);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".aliases");
            }
            throw e;
        }
        try {
            FfiConverterString.checkType(value.charset);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".charset");
            }
            throw e;
        }
        try {
            FfiConverterTypeSearchEngineClassification.checkType(value.classification);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".classification");
            }
            throw e;
        }
        try {
            FfiConverterString.checkType(value.identifier);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".identifier");
            }
            throw e;
        }
        try {
            FfiConverterOptionalString.checkType(value.isNewUntil);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".isNewUntil");
            }
            throw e;
        }
        try {
            FfiConverterString.checkType(value.name);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".name");
            }
            throw e;
        }
        try {
            FfiConverterBoolean.checkType(value.optional);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".optional");
            }
            throw e;
        }
        try {
            FfiConverterString.checkType(value.partnerCode);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".partnerCode");
            }
            throw e;
        }
        try {
            FfiConverterString.checkType(value.telemetrySuffix);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".telemetrySuffix");
            }
            throw e;
        }
        try {
            FfiConverterTypeSearchEngineUrls.checkType(value.urls);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".urls");
            }
            throw e;
        }
        try {
            FfiConverterOptionalUInt32.checkType(value.orderHint);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".orderHint");
            }
            throw e;
        }
        try {
            FfiConverterOptionalString.checkType(value.clickUrl);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".clickUrl");
            }
            throw e;
        }
    }
}
// Export the FFIConverter object to make external types work.
export class FfiConverterSequenceTypeSearchEngineDefinition extends FfiConverterArrayBuffer {
    static read(dataStream) {
        const len = dataStream.readInt32();
        const arr = [];
        for (let i = 0; i < len; i++) {
            arr.push(FfiConverterTypeSearchEngineDefinition.read(dataStream));
        }
        return arr;
    }

    static write(dataStream, value) {
        dataStream.writeInt32(value.length);
        value.forEach((innerValue) => {
            FfiConverterTypeSearchEngineDefinition.write(dataStream, innerValue);
        })
    }

    static computeSize(value) {
        // The size of the length
        let size = 4;
        for (const innerValue of value) {
            size += FfiConverterTypeSearchEngineDefinition.computeSize(innerValue);
        }
        return size;
    }

    static checkType(value) {
        if (!Array.isArray(value)) {
            throw new UniFFITypeError(`${value} is not an array`);
        }
        value.forEach((innerValue, idx) => {
            try {
                FfiConverterTypeSearchEngineDefinition.checkType(innerValue);
            } catch (e) {
                if (e instanceof UniFFITypeError) {
                    e.addItemDescriptionPart(`[${idx}]`);
                }
                throw e;
            }
        })
    }
}
/**
 * Details of the search engines to display to the user, generated as a result
 * of processing the search configuration.
 */
export class RefinedSearchConfig {
    constructor(
        {
            engines, 
            appDefaultEngineId, 
            appPrivateDefaultEngineId
        } = {
            engines: undefined, 
            appDefaultEngineId: undefined, 
            appPrivateDefaultEngineId: undefined
        }
    ) {
        try {
            FfiConverterSequenceTypeSearchEngineDefinition.checkType(engines)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("engines");
            }
            throw e;
        }
        try {
            FfiConverterOptionalString.checkType(appDefaultEngineId)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("appDefaultEngineId");
            }
            throw e;
        }
        try {
            FfiConverterOptionalString.checkType(appPrivateDefaultEngineId)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("appPrivateDefaultEngineId");
            }
            throw e;
        }
        /**
         * A sorted list of engines. Clients may use the engine in the order that
         * this list is specified, or they may implement their own order if they
         * have other requirements.
         * 
         * The application default engines should not be assumed from this order in
         * case of future changes.
         * 
         * The sort order is:
         * 
         * * Application Default Engine
         * * Application Default Engine for Private Mode (if specified & different)
         * * Engines sorted by descending `SearchEngineDefinition.orderHint`
         * * Any other engines in alphabetical order (locale based comparison)
         * @type {Array.<SearchEngineDefinition>}
         */
        this.engines = engines;
        /**
         * The identifier of the engine that should be used for the application
         * default engine. If this is undefined, an error has occurred, and the
         * application should either default to the first engine in the engines
         * list or otherwise handle appropriately.
         * @type {?string}
         */
        this.appDefaultEngineId = appDefaultEngineId;
        /**
         * If specified, the identifier of the engine that should be used for the
         * application default engine in private browsing mode.
         * Only desktop uses this currently.
         * @type {?string}
         */
        this.appPrivateDefaultEngineId = appPrivateDefaultEngineId;
    }

    equals(other) {
        return (
            this.engines == other.engines
            && this.appDefaultEngineId == other.appDefaultEngineId
            && this.appPrivateDefaultEngineId == other.appPrivateDefaultEngineId
        )
    }
}

// Export the FFIConverter object to make external types work.
export class FfiConverterTypeRefinedSearchConfig extends FfiConverterArrayBuffer {
    static read(dataStream) {
        return new RefinedSearchConfig({
            engines: FfiConverterSequenceTypeSearchEngineDefinition.read(dataStream),
            appDefaultEngineId: FfiConverterOptionalString.read(dataStream),
            appPrivateDefaultEngineId: FfiConverterOptionalString.read(dataStream),
        });
    }
    static write(dataStream, value) {
        FfiConverterSequenceTypeSearchEngineDefinition.write(dataStream, value.engines);
        FfiConverterOptionalString.write(dataStream, value.appDefaultEngineId);
        FfiConverterOptionalString.write(dataStream, value.appPrivateDefaultEngineId);
    }

    static computeSize(value) {
        let totalSize = 0;
        totalSize += FfiConverterSequenceTypeSearchEngineDefinition.computeSize(value.engines);
        totalSize += FfiConverterOptionalString.computeSize(value.appDefaultEngineId);
        totalSize += FfiConverterOptionalString.computeSize(value.appPrivateDefaultEngineId);
        return totalSize
    }

    static checkType(value) {
        super.checkType(value);
        if (!(value instanceof RefinedSearchConfig)) {
            throw new UniFFITypeError(`Expected 'RefinedSearchConfig', found '${typeof value}'`);
        }
        try {
            FfiConverterSequenceTypeSearchEngineDefinition.checkType(value.engines);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".engines");
            }
            throw e;
        }
        try {
            FfiConverterOptionalString.checkType(value.appDefaultEngineId);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".appDefaultEngineId");
            }
            throw e;
        }
        try {
            FfiConverterOptionalString.checkType(value.appPrivateDefaultEngineId);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".appPrivateDefaultEngineId");
            }
            throw e;
        }
    }
}

/**
 * The list of possible update channels for a user's build.
 * Use `default` for a self-build or an unknown channel.
 */
export const SearchUpdateChannel = Object.freeze({
    /**
     * NIGHTLY
     */
    NIGHTLY: 1,
    /**
     * AURORA
     */
    AURORA: 2,
    /**
     * BETA
     */
    BETA: 3,
    /**
     * RELEASE
     */
    RELEASE: 4,
    /**
     * ESR
     */
    ESR: 5,
    /**
     * DEFAULT
     */
    DEFAULT: 6,
});

// Export the FFIConverter object to make external types work.
export class FfiConverterTypeSearchUpdateChannel extends FfiConverterArrayBuffer {
    static #validValues = Object.values(SearchUpdateChannel)

    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
            case 2:
                return SearchUpdateChannel.AURORA
            case 3:
                return SearchUpdateChannel.BETA
            case 4:
                return SearchUpdateChannel.RELEASE
            case 5:
                return SearchUpdateChannel.ESR
            case 6:
                return SearchUpdateChannel.DEFAULT
            default:
                throw new UniFFITypeError("Unknown SearchUpdateChannel variant");
        }
    }

    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;
        }
        if (value === SearchUpdateChannel.AURORA) {
            dataStream.writeInt32(2);
            return;
        }
        if (value === SearchUpdateChannel.BETA) {
            dataStream.writeInt32(3);
            return;
        }
        if (value === SearchUpdateChannel.RELEASE) {
            dataStream.writeInt32(4);
            return;
        }
        if (value === SearchUpdateChannel.ESR) {
            dataStream.writeInt32(5);
            return;
        }
        if (value === SearchUpdateChannel.DEFAULT) {
            dataStream.writeInt32(6);
            return;
        }
        throw new UniFFITypeError("Unknown SearchUpdateChannel variant");
    }

    static computeSize(value) {
        return 4;
    }

    static checkType(value) {
      // Check that the value is a valid enum variant
      if (!this.#validValues.includes(value)) {
          throw new UniFFITypeError(`${value} is not a valid value for SearchUpdateChannel`);
      }
    }
}

/**
 * The list of possible application names that are currently supported.
 */
export const SearchApplicationName = Object.freeze({
    /**
     * FIREFOX_ANDROID
     */
    FIREFOX_ANDROID: 1,
    /**
     * FIREFOX_IOS
     */
    FIREFOX_IOS: 2,
    /**
     * FOCUS_ANDROID
     */
    FOCUS_ANDROID: 3,
    /**
     * FOCUS_IOS
     */
    FOCUS_IOS: 4,
    /**
     * FIREFOX
     */
    FIREFOX: 5,
});

// Export the FFIConverter object to make external types work.
export class FfiConverterTypeSearchApplicationName extends FfiConverterArrayBuffer {
    static #validValues = Object.values(SearchApplicationName)

    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
            case 2:
                return SearchApplicationName.FIREFOX_IOS
            case 3:
                return SearchApplicationName.FOCUS_ANDROID
            case 4:
                return SearchApplicationName.FOCUS_IOS
            case 5:
                return SearchApplicationName.FIREFOX
            default:
                throw new UniFFITypeError("Unknown SearchApplicationName variant");
        }
    }

    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;
        }
        if (value === SearchApplicationName.FIREFOX_IOS) {
            dataStream.writeInt32(2);
            return;
        }
        if (value === SearchApplicationName.FOCUS_ANDROID) {
            dataStream.writeInt32(3);
            return;
        }
        if (value === SearchApplicationName.FOCUS_IOS) {
            dataStream.writeInt32(4);
            return;
        }
        if (value === SearchApplicationName.FIREFOX) {
            dataStream.writeInt32(5);
            return;
        }
        throw new UniFFITypeError("Unknown SearchApplicationName variant");
    }

    static computeSize(value) {
        return 4;
    }

    static checkType(value) {
      // Check that the value is a valid enum variant
      if (!this.#validValues.includes(value)) {
          throw new UniFFITypeError(`${value} is not a valid value for SearchApplicationName`);
      }
    }
}

/**
 * SearchDeviceType
 */
export const SearchDeviceType = Object.freeze({
    /**
     * SMARTPHONE
     */
    SMARTPHONE: 1,
    /**
     * TABLET
     */
    TABLET: 2,
    /**
     * NONE
     */
    NONE: 3,
});

// Export the FFIConverter object to make external types work.
export class FfiConverterTypeSearchDeviceType extends FfiConverterArrayBuffer {
    static #validValues = Object.values(SearchDeviceType)

    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
            case 2:
                return SearchDeviceType.TABLET
            case 3:
                return SearchDeviceType.NONE
            default:
                throw new UniFFITypeError("Unknown SearchDeviceType variant");
        }
    }

    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;
        }
        if (value === SearchDeviceType.TABLET) {
            dataStream.writeInt32(2);
            return;
        }
        if (value === SearchDeviceType.NONE) {
            dataStream.writeInt32(3);
            return;
        }
        throw new UniFFITypeError("Unknown SearchDeviceType variant");
    }

    static computeSize(value) {
        return 4;
    }

    static checkType(value) {
      // Check that the value is a valid enum variant
      if (!this.#validValues.includes(value)) {
          throw new UniFFITypeError(`${value} is not a valid value for SearchDeviceType`);
      }
    }
}
/**
 * The user's environment that is used for filtering the search configuration.
 */
export class SearchUserEnvironment {
    constructor(
        {
            locale, 
            region, 
            updateChannel, 
            distributionId, 
            experiment, 
            appName, 
            version, 
            deviceType
        } = {
            locale: undefined, 
            region: undefined, 
            updateChannel: undefined, 
            distributionId: undefined, 
            experiment: undefined, 
            appName: undefined, 
            version: undefined, 
            deviceType: undefined
        }
    ) {
        try {
            FfiConverterString.checkType(locale)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("locale");
            }
            throw e;
        }
        try {
            FfiConverterString.checkType(region)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("region");
            }
            throw e;
        }
        try {
            FfiConverterTypeSearchUpdateChannel.checkType(updateChannel)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("updateChannel");
            }
            throw e;
        }
        try {
            FfiConverterString.checkType(distributionId)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("distributionId");
            }
            throw e;
        }
        try {
            FfiConverterString.checkType(experiment)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("experiment");
            }
            throw e;
        }
        try {
            FfiConverterTypeSearchApplicationName.checkType(appName)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("appName");
            }
            throw e;
        }
        try {
            FfiConverterString.checkType(version)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("version");
            }
            throw e;
        }
        try {
            FfiConverterTypeSearchDeviceType.checkType(deviceType)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("deviceType");
            }
            throw e;
        }
        /**
         * The current locale of the application that the user is using.
         * @type {string}
         */
        this.locale = locale;
        /**
         * The home region that the user is currently identified as being within.
         * On desktop & android there is a 14 day lag after detecting a region
         * change before the home region changes. TBD: iOS?
         * @type {string}
         */
        this.region = region;
        /**
         * The update channel of the user's build.
         * @type {SearchUpdateChannel[keyof SearchUpdateChannel]}
         */
        this.updateChannel = updateChannel;
        /**
         * The distribution id for the user's build.
         * @type {string}
         */
        this.distributionId = distributionId;
        /**
         * The search related experiment id that the user is included within. On
         * desktop this is the `searchConfiguration.experiment` variable.
         * @type {string}
         */
        this.experiment = experiment;
        /**
         * The application name that the user is using.
         * @type {SearchApplicationName[keyof SearchApplicationName]}
         */
        this.appName = appName;
        /**
         * The application version that the user is using.
         * @type {string}
         */
        this.version = version;
        /**
         * The device type that the user is using.
         * @type {SearchDeviceType[keyof SearchDeviceType]}
         */
        this.deviceType = deviceType;
    }

    equals(other) {
        return (
            this.locale == other.locale
            && this.region == other.region
            && this.updateChannel == other.updateChannel
            && this.distributionId == other.distributionId
            && this.experiment == other.experiment
            && this.appName == other.appName
            && this.version == other.version
            && this.deviceType == other.deviceType
        )
    }
}

// Export the FFIConverter object to make external types work.
export class FfiConverterTypeSearchUserEnvironment extends FfiConverterArrayBuffer {
    static read(dataStream) {
        return new SearchUserEnvironment({
            locale: FfiConverterString.read(dataStream),
            region: FfiConverterString.read(dataStream),
            updateChannel: FfiConverterTypeSearchUpdateChannel.read(dataStream),
            distributionId: FfiConverterString.read(dataStream),
            experiment: FfiConverterString.read(dataStream),
            appName: FfiConverterTypeSearchApplicationName.read(dataStream),
            version: FfiConverterString.read(dataStream),
            deviceType: FfiConverterTypeSearchDeviceType.read(dataStream),
        });
    }
    static write(dataStream, value) {
        FfiConverterString.write(dataStream, value.locale);
        FfiConverterString.write(dataStream, value.region);
        FfiConverterTypeSearchUpdateChannel.write(dataStream, value.updateChannel);
        FfiConverterString.write(dataStream, value.distributionId);
        FfiConverterString.write(dataStream, value.experiment);
        FfiConverterTypeSearchApplicationName.write(dataStream, value.appName);
        FfiConverterString.write(dataStream, value.version);
        FfiConverterTypeSearchDeviceType.write(dataStream, value.deviceType);
    }

    static computeSize(value) {
        let totalSize = 0;
        totalSize += FfiConverterString.computeSize(value.locale);
        totalSize += FfiConverterString.computeSize(value.region);
        totalSize += FfiConverterTypeSearchUpdateChannel.computeSize(value.updateChannel);
        totalSize += FfiConverterString.computeSize(value.distributionId);
        totalSize += FfiConverterString.computeSize(value.experiment);
        totalSize += FfiConverterTypeSearchApplicationName.computeSize(value.appName);
        totalSize += FfiConverterString.computeSize(value.version);
        totalSize += FfiConverterTypeSearchDeviceType.computeSize(value.deviceType);
        return totalSize
    }

    static checkType(value) {
        super.checkType(value);
        if (!(value instanceof SearchUserEnvironment)) {
            throw new UniFFITypeError(`Expected 'SearchUserEnvironment', found '${typeof value}'`);
        }
        try {
            FfiConverterString.checkType(value.locale);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".locale");
            }
            throw e;
        }
        try {
            FfiConverterString.checkType(value.region);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".region");
            }
            throw e;
        }
        try {
            FfiConverterTypeSearchUpdateChannel.checkType(value.updateChannel);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".updateChannel");
            }
            throw e;
        }
        try {
            FfiConverterString.checkType(value.distributionId);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".distributionId");
            }
            throw e;
        }
        try {
            FfiConverterString.checkType(value.experiment);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".experiment");
            }
            throw e;
        }
        try {
            FfiConverterTypeSearchApplicationName.checkType(value.appName);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".appName");
            }
            throw e;
        }
        try {
            FfiConverterString.checkType(value.version);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".version");
            }
            throw e;
        }
        try {
            FfiConverterTypeSearchDeviceType.checkType(value.deviceType);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".deviceType");
            }
            throw e;
        }
    }
}

/**
 * SearchApiError
 */
export class SearchApiError extends Error {}


/**
 * Other
 */
export class Other extends SearchApiError {

    constructor(
        reason,
        ...params
    ) {
        const message = `reason: ${ reason }`;
        super(message, ...params);
        this.reason = reason;
    }
    toString() {
        return `Other: ${super.toString()}`
    }
}

// Export the FFIConverter object to make external types work.
export class FfiConverterTypeSearchApiError extends FfiConverterArrayBuffer {
    static read(dataStream) {
        switch (dataStream.readInt32()) {
            case 1:
                return new Other(
                    FfiConverterString.read(dataStream)
                    );
            default:
                throw new UniFFITypeError("Unknown SearchApiError variant");
        }
    }
    static computeSize(value) {
        // Size of the Int indicating the variant
        let totalSize = 4;
        if (value instanceof Other) {
            totalSize += FfiConverterString.computeSize(value.reason);
            return totalSize;
        }
        throw new UniFFITypeError("Unknown SearchApiError variant");
    }
    static write(dataStream, value) {
        if (value instanceof Other) {
            dataStream.writeInt32(1);
            FfiConverterString.write(dataStream, value.reason);
            return;
        }
        throw new UniFFITypeError("Unknown SearchApiError variant");
    }

    static errorClass = SearchApiError;
}
import {
  FfiConverterTypeRemoteSettingsService,
} from "./RustRemoteSettings.sys.mjs";

// Export the FFIConverter object to make external types work.
export { FfiConverterTypeRemoteSettingsService };

/**
 * SearchEngineSelector parses the JSON configuration for
 * search engines and returns the applicable engines depending
 * on their region + locale.
 */
export class SearchEngineSelectorInterface {
    /**
     * Clears the search configuration from memory if it is known that it is
     * not required for a time, e.g. if the configuration will only be re-filtered
     * after an app/environment update.
     */
    clearSearchConfig() {
      throw Error("clearSearchConfig not implemented");
    }
    /**
     * Filters the search configuration with the user's given environment,
     * and returns the set of engines and parameters that should be presented
     * to the user.
     * @param {SearchUserEnvironment} userEnvironment
     * @returns {RefinedSearchConfig}
     */
    filterEngineConfiguration(
        userEnvironment) {
      throw Error("filterEngineConfiguration not implemented");
    }
    /**
     * setConfigOverrides
     * @param {string} overrides
     */
    setConfigOverrides(
        overrides) {
      throw Error("setConfigOverrides not implemented");
    }
    /**
     * Sets the search configuration from the given string. If the configuration
     * string is unchanged since the last update, the cached configuration is
     * reused to avoid unnecessary reprocessing. This helps optimize performance,
     * particularly during test runs where the same configuration may be used
     * repeatedly.
     * @param {string} configuration
     */
    setSearchConfig(
        configuration) {
      throw Error("setSearchConfig not implemented");
    }
    /**
     * Sets the RemoteSettingsService to use. The selector will create the
     * relevant remote settings client(s) from the service.
     * 
     * # Params:
     * - `service`: The remote settings service instance for the application.
     * - `options`: The remote settings options to be passed to the client(s).
     * - `apply_engine_overrides`: Whether or not to apply overrides from
     * `search-config-v2-overrides` to the selected engines. Should be false unless the
     * application supports the click URL feature.
     * @param {RemoteSettingsService} service
     * @param {boolean} applyEngineOverrides
     */
    async useRemoteSettingsServer(
        service, 
        applyEngineOverrides) {
      throw Error("useRemoteSettingsServer not implemented");
    }

}

/**
 * SearchEngineSelector parses the JSON configuration for
 * search engines and returns the applicable engines depending
 * on their region + locale.
 */
export class SearchEngineSelector extends SearchEngineSelectorInterface {
    // Use `init` to instantiate this class.
    // DO NOT USE THIS CONSTRUCTOR DIRECTLY
    constructor(opts) {
        super();
        if (!Object.prototype.hasOwnProperty.call(opts, constructUniffiObject)) {
            throw new UniFFIError("Attempting to construct an int using the JavaScript constructor directly" +
            "Please use a UDL defined constructor, or the init function for the primary constructor")
        }
        if (!(opts[constructUniffiObject] instanceof UniFFIPointer)) {
            throw new UniFFIError("Attempting to create a UniFFI object with a pointer that is not an instance of UniFFIPointer")
        }
        this[uniffiObjectPtr] = opts[constructUniffiObject];
    }
    /**
     * init
     * @returns {SearchEngineSelector}
     */
    static init() {
       
        const result = UniFFIScaffolding.callSync(
            166, // uniffi_search_fn_constructor_searchengineselector_new
        )
        return handleRustResult(
            result,
            FfiConverterTypeSearchEngineSelector.lift.bind(FfiConverterTypeSearchEngineSelector),
            null,
        )
    }

    /**
     * Clears the search configuration from memory if it is known that it is
     * not required for a time, e.g. if the configuration will only be re-filtered
     * after an app/environment update.
     */
    clearSearchConfig() {
       
        const result = UniFFIScaffolding.callSync(
            167, // uniffi_search_fn_method_searchengineselector_clear_search_config
            FfiConverterTypeSearchEngineSelector.lowerReceiver(this),
        )
        return handleRustResult(
            result,
            (result) => undefined,
            null,
        )
    }

    /**
     * Filters the search configuration with the user's given environment,
     * and returns the set of engines and parameters that should be presented
     * to the user.
     * @param {SearchUserEnvironment} userEnvironment
     * @returns {RefinedSearchConfig}
     */
    filterEngineConfiguration(
        userEnvironment) {
       
        FfiConverterTypeSearchUserEnvironment.checkType(userEnvironment);
        const result = UniFFIScaffolding.callSync(
            168, // uniffi_search_fn_method_searchengineselector_filter_engine_configuration
            FfiConverterTypeSearchEngineSelector.lowerReceiver(this),
            FfiConverterTypeSearchUserEnvironment.lower(userEnvironment),
        )
        return handleRustResult(
            result,
            FfiConverterTypeRefinedSearchConfig.lift.bind(FfiConverterTypeRefinedSearchConfig),
            FfiConverterTypeSearchApiError.lift.bind(FfiConverterTypeSearchApiError),
        )
    }

    /**
     * setConfigOverrides
     * @param {string} overrides
     */
    setConfigOverrides(
        overrides) {
       
        FfiConverterString.checkType(overrides);
        const result = UniFFIScaffolding.callSync(
            169, // uniffi_search_fn_method_searchengineselector_set_config_overrides
            FfiConverterTypeSearchEngineSelector.lowerReceiver(this),
            FfiConverterString.lower(overrides),
        )
        return handleRustResult(
            result,
            (result) => undefined,
            FfiConverterTypeSearchApiError.lift.bind(FfiConverterTypeSearchApiError),
        )
    }

    /**
     * Sets the search configuration from the given string. If the configuration
     * string is unchanged since the last update, the cached configuration is
     * reused to avoid unnecessary reprocessing. This helps optimize performance,
     * particularly during test runs where the same configuration may be used
     * repeatedly.
     * @param {string} configuration
     */
    setSearchConfig(
        configuration) {
       
        FfiConverterString.checkType(configuration);
        const result = UniFFIScaffolding.callSync(
            170, // uniffi_search_fn_method_searchengineselector_set_search_config
            FfiConverterTypeSearchEngineSelector.lowerReceiver(this),
            FfiConverterString.lower(configuration),
        )
        return handleRustResult(
            result,
            (result) => undefined,
            FfiConverterTypeSearchApiError.lift.bind(FfiConverterTypeSearchApiError),
        )
    }

    /**
     * Sets the RemoteSettingsService to use. The selector will create the
     * relevant remote settings client(s) from the service.
     * 
     * # Params:
     * - `service`: The remote settings service instance for the application.
     * - `options`: The remote settings options to be passed to the client(s).
     * - `apply_engine_overrides`: Whether or not to apply overrides from
     * `search-config-v2-overrides` to the selected engines. Should be false unless the
     * application supports the click URL feature.
     * @param {RemoteSettingsService} service
     * @param {boolean} applyEngineOverrides
     */
    async useRemoteSettingsServer(
        service, 
        applyEngineOverrides) {
       
        FfiConverterTypeRemoteSettingsService.checkType(service);
        FfiConverterBoolean.checkType(applyEngineOverrides);
        const result = await UniFFIScaffolding.callAsyncWrapper(
            171, // uniffi_search_fn_method_searchengineselector_use_remote_settings_server
            FfiConverterTypeSearchEngineSelector.lowerReceiver(this),
            FfiConverterTypeRemoteSettingsService.lower(service),
            FfiConverterBoolean.lower(applyEngineOverrides),
        )
        return handleRustResult(
            result,
            (result) => undefined,
            null,
        )
    }

}

// Export the FFIConverter object to make external types work.
export class FfiConverterTypeSearchEngineSelector extends FfiConverter {
    static lift(value) {
        const opts = {};
        opts[constructUniffiObject] = value;
        return new SearchEngineSelector(opts);
    }

    static lower(value) {
        const ptr = value[uniffiObjectPtr];
        if (!(ptr instanceof UniFFIPointer)) {
            throw new UniFFITypeError("Object is not a 'SearchEngineSelector' instance");
        }
        return ptr;
    }

    static lowerReceiver(value) {
        // This works exactly the same as lower for non-trait interfaces
        return this.lower(value);
    }

    static read(dataStream) {
        return this.lift(dataStream.readPointer(20));
    }

    static write(dataStream, value) {
        dataStream.writePointer(20, this.lower(value));
    }

    static computeSize(value) {
        return 8;
    }
}





