// This file was autogenerated by some hot garbage in the `uniffi` crate.
// Trust me, you don't want to mess with it!

// swiftlint:disable all
import Foundation

// Depending on the consumer's build setup, the low-level FFI code
// might be in a separate module, or it might be compiled inline into
// this module. This is a bit of light hackery to work with both.
#if canImport(MozillaRustComponents)
import MozillaRustComponents
#endif

fileprivate extension RustBuffer {
    // Allocate a new buffer, copying the contents of a `UInt8` array.
    init(bytes: [UInt8]) {
        let rbuf = bytes.withUnsafeBufferPointer { ptr in
            RustBuffer.from(ptr)
        }
        self.init(capacity: rbuf.capacity, len: rbuf.len, data: rbuf.data)
    }

    static func empty() -> RustBuffer {
        RustBuffer(capacity: 0, len:0, data: nil)
    }

    static func from(_ ptr: UnsafeBufferPointer<UInt8>) -> RustBuffer {
        try! rustCall { ffi_nimbus_rustbuffer_from_bytes(ForeignBytes(bufferPointer: ptr), $0) }
    }

    // Frees the buffer in place.
    // The buffer must not be used after this is called.
    func deallocate() {
        try! rustCall { ffi_nimbus_rustbuffer_free(self, $0) }
    }
}

fileprivate extension ForeignBytes {
    init(bufferPointer: UnsafeBufferPointer<UInt8>) {
        self.init(len: Int32(bufferPointer.count), data: bufferPointer.baseAddress)
    }
}

// For every type used in the interface, we provide helper methods for conveniently
// lifting and lowering that type from C-compatible data, and for reading and writing
// values of that type in a buffer.

// Helper classes/extensions that don't change.
// Someday, this will be in a library of its own.

fileprivate extension Data {
    init(rustBuffer: RustBuffer) {
        self.init(
            bytesNoCopy: rustBuffer.data!,
            count: Int(rustBuffer.len),
            deallocator: .none
        )
    }
}

// Define reader functionality.  Normally this would be defined in a class or
// struct, but we use standalone functions instead in order to make external
// types work.
//
// With external types, one swift source file needs to be able to call the read
// method on another source file's FfiConverter, but then what visibility
// should Reader have?
// - If Reader is fileprivate, then this means the read() must also
//   be fileprivate, which doesn't work with external types.
// - If Reader is internal/public, we'll get compile errors since both source
//   files will try define the same type.
//
// Instead, the read() method and these helper functions input a tuple of data

fileprivate func createReader(data: Data) -> (data: Data, offset: Data.Index) {
    (data: data, offset: 0)
}

// Reads an integer at the current offset, in big-endian order, and advances
// the offset on success. Throws if reading the integer would move the
// offset past the end of the buffer.
fileprivate func readInt<T: FixedWidthInteger>(_ reader: inout (data: Data, offset: Data.Index)) throws -> T {
    let range = reader.offset..<reader.offset + MemoryLayout<T>.size
    guard reader.data.count >= range.upperBound else {
        throw UniffiInternalError.bufferOverflow
    }
    if T.self == UInt8.self {
        let value = reader.data[reader.offset]
        reader.offset += 1
        return value as! T
    }
    var value: T = 0
    let _ = withUnsafeMutableBytes(of: &value, { reader.data.copyBytes(to: $0, from: range)})
    reader.offset = range.upperBound
    return value.bigEndian
}

// Reads an arbitrary number of bytes, to be used to read
// raw bytes, this is useful when lifting strings
fileprivate func readBytes(_ reader: inout (data: Data, offset: Data.Index), count: Int) throws -> Array<UInt8> {
    let range = reader.offset..<(reader.offset+count)
    guard reader.data.count >= range.upperBound else {
        throw UniffiInternalError.bufferOverflow
    }
    var value = [UInt8](repeating: 0, count: count)
    value.withUnsafeMutableBufferPointer({ buffer in
        reader.data.copyBytes(to: buffer, from: range)
    })
    reader.offset = range.upperBound
    return value
}

// Reads a float at the current offset.
fileprivate func readFloat(_ reader: inout (data: Data, offset: Data.Index)) throws -> Float {
    return Float(bitPattern: try readInt(&reader))
}

// Reads a float at the current offset.
fileprivate func readDouble(_ reader: inout (data: Data, offset: Data.Index)) throws -> Double {
    return Double(bitPattern: try readInt(&reader))
}

// Indicates if the offset has reached the end of the buffer.
fileprivate func hasRemaining(_ reader: (data: Data, offset: Data.Index)) -> Bool {
    return reader.offset < reader.data.count
}

// Define writer functionality.  Normally this would be defined in a class or
// struct, but we use standalone functions instead in order to make external
// types work.  See the above discussion on Readers for details.

fileprivate func createWriter() -> [UInt8] {
    return []
}

fileprivate func writeBytes<S>(_ writer: inout [UInt8], _ byteArr: S) where S: Sequence, S.Element == UInt8 {
    writer.append(contentsOf: byteArr)
}

// Writes an integer in big-endian order.
//
// Warning: make sure what you are trying to write
// is in the correct type!
fileprivate func writeInt<T: FixedWidthInteger>(_ writer: inout [UInt8], _ value: T) {
    var value = value.bigEndian
    withUnsafeBytes(of: &value) { writer.append(contentsOf: $0) }
}

fileprivate func writeFloat(_ writer: inout [UInt8], _ value: Float) {
    writeInt(&writer, value.bitPattern)
}

fileprivate func writeDouble(_ writer: inout [UInt8], _ value: Double) {
    writeInt(&writer, value.bitPattern)
}

// Protocol for types that transfer other types across the FFI. This is
// analogous to the Rust trait of the same name.
fileprivate protocol FfiConverter {
    associatedtype FfiType
    associatedtype SwiftType

    static func lift(_ value: FfiType) throws -> SwiftType
    static func lower(_ value: SwiftType) -> FfiType
    static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType
    static func write(_ value: SwiftType, into buf: inout [UInt8])
}

// Types conforming to `Primitive` pass themselves directly over the FFI.
fileprivate protocol FfiConverterPrimitive: FfiConverter where FfiType == SwiftType { }

extension FfiConverterPrimitive {
#if swift(>=5.8)
    @_documentation(visibility: private)
#endif
    public static func lift(_ value: FfiType) throws -> SwiftType {
        return value
    }

#if swift(>=5.8)
    @_documentation(visibility: private)
#endif
    public static func lower(_ value: SwiftType) -> FfiType {
        return value
    }
}

// Types conforming to `FfiConverterRustBuffer` lift and lower into a `RustBuffer`.
// Used for complex types where it's hard to write a custom lift/lower.
fileprivate protocol FfiConverterRustBuffer: FfiConverter where FfiType == RustBuffer {}

extension FfiConverterRustBuffer {
#if swift(>=5.8)
    @_documentation(visibility: private)
#endif
    public static func lift(_ buf: RustBuffer) throws -> SwiftType {
        var reader = createReader(data: Data(rustBuffer: buf))
        let value = try read(from: &reader)
        if hasRemaining(reader) {
            throw UniffiInternalError.incompleteData
        }
        buf.deallocate()
        return value
    }

#if swift(>=5.8)
    @_documentation(visibility: private)
#endif
    public static func lower(_ value: SwiftType) -> RustBuffer {
          var writer = createWriter()
          write(value, into: &writer)
          return RustBuffer(bytes: writer)
    }
}
// An error type for FFI errors. These errors occur at the UniFFI level, not
// the library level.
fileprivate enum UniffiInternalError: LocalizedError {
    case bufferOverflow
    case incompleteData
    case unexpectedOptionalTag
    case unexpectedEnumCase
    case unexpectedNullPointer
    case unexpectedRustCallStatusCode
    case unexpectedRustCallError
    case unexpectedStaleHandle
    case rustPanic(_ message: String)

    public var errorDescription: String? {
        switch self {
        case .bufferOverflow: return "Reading the requested value would read past the end of the buffer"
        case .incompleteData: return "The buffer still has data after lifting its containing value"
        case .unexpectedOptionalTag: return "Unexpected optional tag; should be 0 or 1"
        case .unexpectedEnumCase: return "Raw enum value doesn't match any cases"
        case .unexpectedNullPointer: return "Raw pointer value was null"
        case .unexpectedRustCallStatusCode: return "Unexpected RustCallStatus code"
        case .unexpectedRustCallError: return "CALL_ERROR but no errorClass specified"
        case .unexpectedStaleHandle: return "The object in the handle map has been dropped already"
        case let .rustPanic(message): return message
        }
    }
}

fileprivate extension NSLock {
    func withLock<T>(f: () throws -> T) rethrows -> T {
        self.lock()
        defer { self.unlock() }
        return try f()
    }
}

fileprivate let CALL_SUCCESS: Int8 = 0
fileprivate let CALL_ERROR: Int8 = 1
fileprivate let CALL_UNEXPECTED_ERROR: Int8 = 2
fileprivate let CALL_CANCELLED: Int8 = 3

fileprivate extension RustCallStatus {
    init() {
        self.init(
            code: CALL_SUCCESS,
            errorBuf: RustBuffer.init(
                capacity: 0,
                len: 0,
                data: nil
            )
        )
    }
}

private func rustCall<T>(_ callback: (UnsafeMutablePointer<RustCallStatus>) -> T) throws -> T {
    let neverThrow: ((RustBuffer) throws -> Never)? = nil
    return try makeRustCall(callback, errorHandler: neverThrow)
}

private func rustCallWithError<T, E: Swift.Error>(
    _ errorHandler: @escaping (RustBuffer) throws -> E,
    _ callback: (UnsafeMutablePointer<RustCallStatus>) -> T) throws -> T {
    try makeRustCall(callback, errorHandler: errorHandler)
}

private func makeRustCall<T, E: Swift.Error>(
    _ callback: (UnsafeMutablePointer<RustCallStatus>) -> T,
    errorHandler: ((RustBuffer) throws -> E)?
) throws -> T {
    uniffiEnsureNimbusInitialized()
    var callStatus = RustCallStatus.init()
    let returnedVal = callback(&callStatus)
    try uniffiCheckCallStatus(callStatus: callStatus, errorHandler: errorHandler)
    return returnedVal
}

private func uniffiCheckCallStatus<E: Swift.Error>(
    callStatus: RustCallStatus,
    errorHandler: ((RustBuffer) throws -> E)?
) throws {
    switch callStatus.code {
        case CALL_SUCCESS:
            return

        case CALL_ERROR:
            if let errorHandler = errorHandler {
                throw try errorHandler(callStatus.errorBuf)
            } else {
                callStatus.errorBuf.deallocate()
                throw UniffiInternalError.unexpectedRustCallError
            }

        case CALL_UNEXPECTED_ERROR:
            // When the rust code sees a panic, it tries to construct a RustBuffer
            // with the message.  But if that code panics, then it just sends back
            // an empty buffer.
            if callStatus.errorBuf.len > 0 {
                throw UniffiInternalError.rustPanic(try FfiConverterString.lift(callStatus.errorBuf))
            } else {
                callStatus.errorBuf.deallocate()
                throw UniffiInternalError.rustPanic("Rust panic")
            }

        case CALL_CANCELLED:
            fatalError("Cancellation not supported yet")

        default:
            throw UniffiInternalError.unexpectedRustCallStatusCode
    }
}

private func uniffiTraitInterfaceCall<T>(
    callStatus: UnsafeMutablePointer<RustCallStatus>,
    makeCall: () throws -> T,
    writeReturn: (T) -> ()
) {
    do {
        try writeReturn(makeCall())
    } catch let error {
        callStatus.pointee.code = CALL_UNEXPECTED_ERROR
        callStatus.pointee.errorBuf = FfiConverterString.lower(String(describing: error))
    }
}

private func uniffiTraitInterfaceCallWithError<T, E>(
    callStatus: UnsafeMutablePointer<RustCallStatus>,
    makeCall: () throws -> T,
    writeReturn: (T) -> (),
    lowerError: (E) -> RustBuffer
) {
    do {
        try writeReturn(makeCall())
    } catch let error as E {
        callStatus.pointee.code = CALL_ERROR
        callStatus.pointee.errorBuf = lowerError(error)
    } catch {
        callStatus.pointee.code = CALL_UNEXPECTED_ERROR
        callStatus.pointee.errorBuf = FfiConverterString.lower(String(describing: error))
    }
}
fileprivate final class UniffiHandleMap<T>: @unchecked Sendable {
    // All mutation happens with this lock held, which is why we implement @unchecked Sendable.
    private let lock = NSLock()
    private var map: [UInt64: T] = [:]
    private var currentHandle: UInt64 = 1

    func insert(obj: T) -> UInt64 {
        lock.withLock {
            let handle = currentHandle
            currentHandle += 1
            map[handle] = obj
            return handle
        }
    }

     func get(handle: UInt64) throws -> T {
        try lock.withLock {
            guard let obj = map[handle] else {
                throw UniffiInternalError.unexpectedStaleHandle
            }
            return obj
        }
    }

    @discardableResult
    func remove(handle: UInt64) throws -> T {
        try lock.withLock {
            guard let obj = map.removeValue(forKey: handle) else {
                throw UniffiInternalError.unexpectedStaleHandle
            }
            return obj
        }
    }

    var count: Int {
        get {
            map.count
        }
    }
}


// Public interface members begin here.


#if swift(>=5.8)
@_documentation(visibility: private)
#endif
fileprivate struct FfiConverterInt32: FfiConverterPrimitive {
    typealias FfiType = Int32
    typealias SwiftType = Int32

    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Int32 {
        return try lift(readInt(&buf))
    }

    public static func write(_ value: Int32, into buf: inout [UInt8]) {
        writeInt(&buf, lower(value))
    }
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
fileprivate struct FfiConverterInt64: FfiConverterPrimitive {
    typealias FfiType = Int64
    typealias SwiftType = Int64

    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Int64 {
        return try lift(readInt(&buf))
    }

    public static func write(_ value: Int64, into buf: inout [UInt8]) {
        writeInt(&buf, lower(value))
    }
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
fileprivate struct FfiConverterDouble: FfiConverterPrimitive {
    typealias FfiType = Double
    typealias SwiftType = Double

    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Double {
        return try lift(readDouble(&buf))
    }

    public static func write(_ value: Double, into buf: inout [UInt8]) {
        writeDouble(&buf, lower(value))
    }
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
fileprivate struct FfiConverterBool : FfiConverter {
    typealias FfiType = Int8
    typealias SwiftType = Bool

    public static func lift(_ value: Int8) throws -> Bool {
        return value != 0
    }

    public static func lower(_ value: Bool) -> Int8 {
        return value ? 1 : 0
    }

    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Bool {
        return try lift(readInt(&buf))
    }

    public static func write(_ value: Bool, into buf: inout [UInt8]) {
        writeInt(&buf, lower(value))
    }
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
fileprivate struct FfiConverterString: FfiConverter {
    typealias SwiftType = String
    typealias FfiType = RustBuffer

    public static func lift(_ value: RustBuffer) throws -> String {
        defer {
            value.deallocate()
        }
        if value.data == nil {
            return String()
        }
        let bytes = UnsafeBufferPointer<UInt8>(start: value.data!, count: Int(value.len))
        return String(bytes: bytes, encoding: String.Encoding.utf8)!
    }

    public static func lower(_ value: String) -> RustBuffer {
        return value.utf8CString.withUnsafeBufferPointer { ptr in
            // The swift string gives us int8_t, we want uint8_t.
            ptr.withMemoryRebound(to: UInt8.self) { ptr in
                // The swift string gives us a trailing null byte, we don't want it.
                let buf = UnsafeBufferPointer(rebasing: ptr.prefix(upTo: ptr.count - 1))
                return RustBuffer.from(buf)
            }
        }
    }

    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> String {
        let len: Int32 = try readInt(&buf)
        return String(bytes: try readBytes(&buf, count: Int(len)), encoding: String.Encoding.utf8)!
    }

    public static func write(_ value: String, into buf: inout [UInt8]) {
        let len = Int32(value.utf8.count)
        writeInt(&buf, len)
        writeBytes(&buf, value.utf8)
    }
}




public protocol NimbusClientProtocol: AnyObject {
    
    /**
     * Advances what the event store thinks is now.
     * This, and `record_past_event` are useful for testing.
     * `by_seconds` must be positive.
     */
    func advanceEventTime(bySeconds: Int64) throws 
    
    /**
     * Apply the updated experiments from the last fetch.
     * After calling this, the list of active experiments might change
     * (there might be new experiments, or old experiments might have expired).
     */
    func applyPendingExperiments() throws  -> [EnrollmentChangeEvent]
    
    func clearEvents() throws 
    
    /**
     * This provides a unified String interpolation library which exposes the application context.
     * It's first use is in the messaging helper, to add extra parameters to URLs.
     */
    func createStringHelper(additionalContext: JsonObject?) throws  -> NimbusStringHelper
    
    /**
     * This provides low level access to the targeting machinery for other uses by the application (e.g. messages)
     * Additional parameters can be added via the optional JSON object. This allows for many JEXL expressions
     * to be run across the same context.
     */
    func createTargetingHelper(additionalContext: JsonObject?) throws  -> NimbusTargetingHelper
    
    func dumpStateToLog() throws 
    
    /**
     * Fetches the list of experiments from the server. This does not affect the list
     * of active experiments or experiment enrolment.
     * Fetched experiments are not applied until `apply_pending_updates()` is called.
     */
    func fetchExperiments() throws 
    
    /**
     * Returns a list of experiments this user is enrolled in.
     */
    func getActiveExperiments() throws  -> [EnrolledExperiment]
    
    /**
     * Returns a list of experiments for this `app_name`, as specified in the `AppContext`.
     * It is not intended to be used to be used for user facing applications.
     */
    func getAvailableExperiments() throws  -> [AvailableExperiment]
    
    /**
     * Returns the branch allocated for a given slug or id.
     */
    func getExperimentBranch(id: String) throws  -> String?
    
    /**
     * Returns a list of experiment branches for a given experiment ID.
     */
    func getExperimentBranches(experimentSlug: String) throws  -> [ExperimentBranch]
    
    func getFeatureConfigVariables(featureId: String) throws  -> String?
    
    /**
     * Getter and setter for user's participation in all experiments.
     * Possible values are:
     * * `true`: the user will not enroll in new experiments, and opt out of all existing ones.
     * * `false`: experiments proceed as usual.
     */
    func getGlobalUserParticipation() throws  -> Bool
    
    /**
     * Initializes the database and caches enough information so that the
     * non-blocking API functions (eg, `get_experiment_branch()`) can
     * return accurate results rather than throwing a "not initialized" error.
     * It's not strictly necessary to call this function - any function that
     * wants to use the database will implicitly initialize too - this exists
     * so that the consuming application can have confidence the non-blocking
     * functions will return data instead of returning an error, and will do
     * the minimum amount of work to achieve that.
     */
    func initialize() throws 
    
    func isFetchEnabled() throws  -> Bool
    
    /**
     * Opt in to a specific branch on a specific experiment. Useful for
     * developers to test their app's interaction with the experiment.
     */
    func optInWithBranch(experimentSlug: String, branch: String) throws  -> [EnrollmentChangeEvent]
    
    /**
     * Opt out of a specific experiment.
     */
    func optOut(experimentSlug: String) throws  -> [EnrollmentChangeEvent]
    
    /**
     * Records an event for the purposes of behavioral targeting.
     * This function is used to record and persist data used for the behavioral
     * targeting such as "core-active" user targeting.
     */
    func recordEvent(eventId: String, count: Int64) throws 
    
    /**
     * Records a Glean event that this feature has been exposed.
     * If the feature is not involved in an experiment, then the event is suppressed.
     * If the feature is only involved in a rollout, then the event is suppressed.
     * If the feature is involved in an experiment, then record the experiment slug
     * and branch.
     * If the feature is involved in an experiment and a rollout, then record only the
     * experiment slug and branch.
     * If the slug is specified, then use this as the experiment, and use it to look up
     * the branch. This is useful for coenrolling features.
     */
    func recordFeatureExposure(featureId: String, slug: String?) 
    
    /**
     * Records a Glean event that this feature configuration is malformed.
     * Accepts a part_id to give the experiment owner or feature implementer
     * clues where to look.
     * The Glean event will always fire, but the content of that event will
     * vary depending on whether then feature is part of an experiment or rollout
     * or not.
     */
    func recordMalformedFeatureConfig(featureId: String, partId: String) 
    
    /**
     * Records an event as if it were in the past.
     * This, and `advance_event_time` are useful for testing.
     * `seconds_ago` must be positive.
     */
    func recordPastEvent(eventId: String, secondsAgo: Int64, count: Int64) throws 
    
    /**
     * These are test-only functions and should never be exposed to production
     * users, as they mess with the "statistical requirements" of the SDK.
     * Reset the enrollments and experiments in the database to an empty state.
     */
    func resetEnrollments() throws 
    
    /**
     * Reset internal state in response to application-level telemetry reset.
     *
     * Consumers should call this method when the user resets the telemetry state of the
     * consuming application, such as by opting out of submitting telemetry. It resets the
     * internal state of the Nimbus client to create a clean break between data collected
     * before and after the reset, including:
     *
     *    * clearing any unique identifiers used internally, so they will reset to
     *      new random values on next use.
     *    * accepting new randomization units, based on application-level ids that
     *      may have also changed.
     *    * disqualifying this client out of any active experiments, to avoid submitting
     *      misleading incomplete data.

     */
    func resetTelemetryIdentifiers() throws  -> [EnrollmentChangeEvent]
    
    /**
     * A convenience method for apps to set the experiments from a local source
     * for either testing, or before the first fetch has finished.
     *
     * Experiments set with this method are not applied until `apply_pending_updates()` is called.
     */
    func setExperimentsLocally(experimentsJson: String) throws 
    
    /**
     * Toggles the enablement of the fetch. If `false`, then calling `fetch_experiments`
     * returns immediately, having not done any fetching from remote settings.
     * This is only useful for QA, and should not be used in production: use
     * `set_global_user_participation` instead.
     */
    func setFetchEnabled(flag: Bool) throws 
    
    func setGlobalUserParticipation(optIn: Bool) throws  -> [EnrollmentChangeEvent]
    
    func unenrollForGeckoPref(prefState: GeckoPrefState, prefUnenrollReason: PrefUnenrollReason) throws  -> [EnrollmentChangeEvent]
    
}
open class NimbusClient: NimbusClientProtocol, @unchecked Sendable {
    fileprivate let pointer: UnsafeMutableRawPointer!

    /// Used to instantiate a [FFIObject] without an actual pointer, for fakes in tests, mostly.
#if swift(>=5.8)
    @_documentation(visibility: private)
#endif
    public struct NoPointer {
        public init() {}
    }

    // TODO: We'd like this to be `private` but for Swifty reasons,
    // we can't implement `FfiConverter` without making this `required` and we can't
    // make it `required` without making it `public`.
    required public init(unsafeFromRawPointer pointer: UnsafeMutableRawPointer) {
        self.pointer = pointer
    }

    // This constructor can be used to instantiate a fake object.
    // - Parameter noPointer: Placeholder value so we can have a constructor separate from the default empty one that may be implemented for classes extending [FFIObject].
    //
    // - Warning:
    //     Any object instantiated with this constructor cannot be passed to an actual Rust-backed object. Since there isn't a backing [Pointer] the FFI lower functions will crash.
#if swift(>=5.8)
    @_documentation(visibility: private)
#endif
    public init(noPointer: NoPointer) {
        self.pointer = nil
    }

#if swift(>=5.8)
    @_documentation(visibility: private)
#endif
    public func uniffiClonePointer() -> UnsafeMutableRawPointer {
        return try! rustCall { uniffi_nimbus_fn_clone_nimbusclient(self.pointer, $0) }
    }
public convenience init(appCtx: AppContext, recordedContext: RecordedContext?, coenrollingFeatureIds: [String], dbpath: String, remoteSettingsConfig: RemoteSettingsConfig?, metricsHandler: MetricsHandler, geckoPrefHandler: GeckoPrefHandler?)throws  {
    let pointer =
        try rustCallWithError(FfiConverterTypeNimbusError_lift) {
    uniffi_nimbus_fn_constructor_nimbusclient_new(
        FfiConverterTypeAppContext_lower(appCtx),
        FfiConverterOptionTypeRecordedContext.lower(recordedContext),
        FfiConverterSequenceString.lower(coenrollingFeatureIds),
        FfiConverterString.lower(dbpath),
        FfiConverterOptionTypeRemoteSettingsConfig.lower(remoteSettingsConfig),
        FfiConverterCallbackInterfaceMetricsHandler_lower(metricsHandler),
        FfiConverterOptionCallbackInterfaceGeckoPrefHandler.lower(geckoPrefHandler),$0
    )
}
    self.init(unsafeFromRawPointer: pointer)
}

    deinit {
        guard let pointer = pointer else {
            return
        }

        try! rustCall { uniffi_nimbus_fn_free_nimbusclient(pointer, $0) }
    }

    

    
    /**
     * Advances what the event store thinks is now.
     * This, and `record_past_event` are useful for testing.
     * `by_seconds` must be positive.
     */
open func advanceEventTime(bySeconds: Int64)throws   {try rustCallWithError(FfiConverterTypeNimbusError_lift) {
    uniffi_nimbus_fn_method_nimbusclient_advance_event_time(self.uniffiClonePointer(),
        FfiConverterInt64.lower(bySeconds),$0
    )
}
}
    
    /**
     * Apply the updated experiments from the last fetch.
     * After calling this, the list of active experiments might change
     * (there might be new experiments, or old experiments might have expired).
     */
open func applyPendingExperiments()throws  -> [EnrollmentChangeEvent]  {
    return try  FfiConverterSequenceTypeEnrollmentChangeEvent.lift(try rustCallWithError(FfiConverterTypeNimbusError_lift) {
    uniffi_nimbus_fn_method_nimbusclient_apply_pending_experiments(self.uniffiClonePointer(),$0
    )
})
}
    
open func clearEvents()throws   {try rustCallWithError(FfiConverterTypeNimbusError_lift) {
    uniffi_nimbus_fn_method_nimbusclient_clear_events(self.uniffiClonePointer(),$0
    )
}
}
    
    /**
     * This provides a unified String interpolation library which exposes the application context.
     * It's first use is in the messaging helper, to add extra parameters to URLs.
     */
open func createStringHelper(additionalContext: JsonObject? = nil)throws  -> NimbusStringHelper  {
    return try  FfiConverterTypeNimbusStringHelper_lift(try rustCallWithError(FfiConverterTypeNimbusError_lift) {
    uniffi_nimbus_fn_method_nimbusclient_create_string_helper(self.uniffiClonePointer(),
        FfiConverterOptionTypeJsonObject.lower(additionalContext),$0
    )
})
}
    
    /**
     * This provides low level access to the targeting machinery for other uses by the application (e.g. messages)
     * Additional parameters can be added via the optional JSON object. This allows for many JEXL expressions
     * to be run across the same context.
     */
open func createTargetingHelper(additionalContext: JsonObject? = nil)throws  -> NimbusTargetingHelper  {
    return try  FfiConverterTypeNimbusTargetingHelper_lift(try rustCallWithError(FfiConverterTypeNimbusError_lift) {
    uniffi_nimbus_fn_method_nimbusclient_create_targeting_helper(self.uniffiClonePointer(),
        FfiConverterOptionTypeJsonObject.lower(additionalContext),$0
    )
})
}
    
open func dumpStateToLog()throws   {try rustCallWithError(FfiConverterTypeNimbusError_lift) {
    uniffi_nimbus_fn_method_nimbusclient_dump_state_to_log(self.uniffiClonePointer(),$0
    )
}
}
    
    /**
     * Fetches the list of experiments from the server. This does not affect the list
     * of active experiments or experiment enrolment.
     * Fetched experiments are not applied until `apply_pending_updates()` is called.
     */
open func fetchExperiments()throws   {try rustCallWithError(FfiConverterTypeNimbusError_lift) {
    uniffi_nimbus_fn_method_nimbusclient_fetch_experiments(self.uniffiClonePointer(),$0
    )
}
}
    
    /**
     * Returns a list of experiments this user is enrolled in.
     */
open func getActiveExperiments()throws  -> [EnrolledExperiment]  {
    return try  FfiConverterSequenceTypeEnrolledExperiment.lift(try rustCallWithError(FfiConverterTypeNimbusError_lift) {
    uniffi_nimbus_fn_method_nimbusclient_get_active_experiments(self.uniffiClonePointer(),$0
    )
})
}
    
    /**
     * Returns a list of experiments for this `app_name`, as specified in the `AppContext`.
     * It is not intended to be used to be used for user facing applications.
     */
open func getAvailableExperiments()throws  -> [AvailableExperiment]  {
    return try  FfiConverterSequenceTypeAvailableExperiment.lift(try rustCallWithError(FfiConverterTypeNimbusError_lift) {
    uniffi_nimbus_fn_method_nimbusclient_get_available_experiments(self.uniffiClonePointer(),$0
    )
})
}
    
    /**
     * Returns the branch allocated for a given slug or id.
     */
open func getExperimentBranch(id: String)throws  -> String?  {
    return try  FfiConverterOptionString.lift(try rustCallWithError(FfiConverterTypeNimbusError_lift) {
    uniffi_nimbus_fn_method_nimbusclient_get_experiment_branch(self.uniffiClonePointer(),
        FfiConverterString.lower(id),$0
    )
})
}
    
    /**
     * Returns a list of experiment branches for a given experiment ID.
     */
open func getExperimentBranches(experimentSlug: String)throws  -> [ExperimentBranch]  {
    return try  FfiConverterSequenceTypeExperimentBranch.lift(try rustCallWithError(FfiConverterTypeNimbusError_lift) {
    uniffi_nimbus_fn_method_nimbusclient_get_experiment_branches(self.uniffiClonePointer(),
        FfiConverterString.lower(experimentSlug),$0
    )
})
}
    
open func getFeatureConfigVariables(featureId: String)throws  -> String?  {
    return try  FfiConverterOptionString.lift(try rustCallWithError(FfiConverterTypeNimbusError_lift) {
    uniffi_nimbus_fn_method_nimbusclient_get_feature_config_variables(self.uniffiClonePointer(),
        FfiConverterString.lower(featureId),$0
    )
})
}
    
    /**
     * Getter and setter for user's participation in all experiments.
     * Possible values are:
     * * `true`: the user will not enroll in new experiments, and opt out of all existing ones.
     * * `false`: experiments proceed as usual.
     */
open func getGlobalUserParticipation()throws  -> Bool  {
    return try  FfiConverterBool.lift(try rustCallWithError(FfiConverterTypeNimbusError_lift) {
    uniffi_nimbus_fn_method_nimbusclient_get_global_user_participation(self.uniffiClonePointer(),$0
    )
})
}
    
    /**
     * Initializes the database and caches enough information so that the
     * non-blocking API functions (eg, `get_experiment_branch()`) can
     * return accurate results rather than throwing a "not initialized" error.
     * It's not strictly necessary to call this function - any function that
     * wants to use the database will implicitly initialize too - this exists
     * so that the consuming application can have confidence the non-blocking
     * functions will return data instead of returning an error, and will do
     * the minimum amount of work to achieve that.
     */
open func initialize()throws   {try rustCallWithError(FfiConverterTypeNimbusError_lift) {
    uniffi_nimbus_fn_method_nimbusclient_initialize(self.uniffiClonePointer(),$0
    )
}
}
    
open func isFetchEnabled()throws  -> Bool  {
    return try  FfiConverterBool.lift(try rustCallWithError(FfiConverterTypeNimbusError_lift) {
    uniffi_nimbus_fn_method_nimbusclient_is_fetch_enabled(self.uniffiClonePointer(),$0
    )
})
}
    
    /**
     * Opt in to a specific branch on a specific experiment. Useful for
     * developers to test their app's interaction with the experiment.
     */
open func optInWithBranch(experimentSlug: String, branch: String)throws  -> [EnrollmentChangeEvent]  {
    return try  FfiConverterSequenceTypeEnrollmentChangeEvent.lift(try rustCallWithError(FfiConverterTypeNimbusError_lift) {
    uniffi_nimbus_fn_method_nimbusclient_opt_in_with_branch(self.uniffiClonePointer(),
        FfiConverterString.lower(experimentSlug),
        FfiConverterString.lower(branch),$0
    )
})
}
    
    /**
     * Opt out of a specific experiment.
     */
open func optOut(experimentSlug: String)throws  -> [EnrollmentChangeEvent]  {
    return try  FfiConverterSequenceTypeEnrollmentChangeEvent.lift(try rustCallWithError(FfiConverterTypeNimbusError_lift) {
    uniffi_nimbus_fn_method_nimbusclient_opt_out(self.uniffiClonePointer(),
        FfiConverterString.lower(experimentSlug),$0
    )
})
}
    
    /**
     * Records an event for the purposes of behavioral targeting.
     * This function is used to record and persist data used for the behavioral
     * targeting such as "core-active" user targeting.
     */
open func recordEvent(eventId: String, count: Int64 = Int64(1))throws   {try rustCallWithError(FfiConverterTypeNimbusError_lift) {
    uniffi_nimbus_fn_method_nimbusclient_record_event(self.uniffiClonePointer(),
        FfiConverterString.lower(eventId),
        FfiConverterInt64.lower(count),$0
    )
}
}
    
    /**
     * Records a Glean event that this feature has been exposed.
     * If the feature is not involved in an experiment, then the event is suppressed.
     * If the feature is only involved in a rollout, then the event is suppressed.
     * If the feature is involved in an experiment, then record the experiment slug
     * and branch.
     * If the feature is involved in an experiment and a rollout, then record only the
     * experiment slug and branch.
     * If the slug is specified, then use this as the experiment, and use it to look up
     * the branch. This is useful for coenrolling features.
     */
open func recordFeatureExposure(featureId: String, slug: String?)  {try! rustCall() {
    uniffi_nimbus_fn_method_nimbusclient_record_feature_exposure(self.uniffiClonePointer(),
        FfiConverterString.lower(featureId),
        FfiConverterOptionString.lower(slug),$0
    )
}
}
    
    /**
     * Records a Glean event that this feature configuration is malformed.
     * Accepts a part_id to give the experiment owner or feature implementer
     * clues where to look.
     * The Glean event will always fire, but the content of that event will
     * vary depending on whether then feature is part of an experiment or rollout
     * or not.
     */
open func recordMalformedFeatureConfig(featureId: String, partId: String)  {try! rustCall() {
    uniffi_nimbus_fn_method_nimbusclient_record_malformed_feature_config(self.uniffiClonePointer(),
        FfiConverterString.lower(featureId),
        FfiConverterString.lower(partId),$0
    )
}
}
    
    /**
     * Records an event as if it were in the past.
     * This, and `advance_event_time` are useful for testing.
     * `seconds_ago` must be positive.
     */
open func recordPastEvent(eventId: String, secondsAgo: Int64, count: Int64 = Int64(1))throws   {try rustCallWithError(FfiConverterTypeNimbusError_lift) {
    uniffi_nimbus_fn_method_nimbusclient_record_past_event(self.uniffiClonePointer(),
        FfiConverterString.lower(eventId),
        FfiConverterInt64.lower(secondsAgo),
        FfiConverterInt64.lower(count),$0
    )
}
}
    
    /**
     * These are test-only functions and should never be exposed to production
     * users, as they mess with the "statistical requirements" of the SDK.
     * Reset the enrollments and experiments in the database to an empty state.
     */
open func resetEnrollments()throws   {try rustCallWithError(FfiConverterTypeNimbusError_lift) {
    uniffi_nimbus_fn_method_nimbusclient_reset_enrollments(self.uniffiClonePointer(),$0
    )
}
}
    
    /**
     * Reset internal state in response to application-level telemetry reset.
     *
     * Consumers should call this method when the user resets the telemetry state of the
     * consuming application, such as by opting out of submitting telemetry. It resets the
     * internal state of the Nimbus client to create a clean break between data collected
     * before and after the reset, including:
     *
     *    * clearing any unique identifiers used internally, so they will reset to
     *      new random values on next use.
     *    * accepting new randomization units, based on application-level ids that
     *      may have also changed.
     *    * disqualifying this client out of any active experiments, to avoid submitting
     *      misleading incomplete data.

     */
open func resetTelemetryIdentifiers()throws  -> [EnrollmentChangeEvent]  {
    return try  FfiConverterSequenceTypeEnrollmentChangeEvent.lift(try rustCallWithError(FfiConverterTypeNimbusError_lift) {
    uniffi_nimbus_fn_method_nimbusclient_reset_telemetry_identifiers(self.uniffiClonePointer(),$0
    )
})
}
    
    /**
     * A convenience method for apps to set the experiments from a local source
     * for either testing, or before the first fetch has finished.
     *
     * Experiments set with this method are not applied until `apply_pending_updates()` is called.
     */
open func setExperimentsLocally(experimentsJson: String)throws   {try rustCallWithError(FfiConverterTypeNimbusError_lift) {
    uniffi_nimbus_fn_method_nimbusclient_set_experiments_locally(self.uniffiClonePointer(),
        FfiConverterString.lower(experimentsJson),$0
    )
}
}
    
    /**
     * Toggles the enablement of the fetch. If `false`, then calling `fetch_experiments`
     * returns immediately, having not done any fetching from remote settings.
     * This is only useful for QA, and should not be used in production: use
     * `set_global_user_participation` instead.
     */
open func setFetchEnabled(flag: Bool)throws   {try rustCallWithError(FfiConverterTypeNimbusError_lift) {
    uniffi_nimbus_fn_method_nimbusclient_set_fetch_enabled(self.uniffiClonePointer(),
        FfiConverterBool.lower(flag),$0
    )
}
}
    
open func setGlobalUserParticipation(optIn: Bool)throws  -> [EnrollmentChangeEvent]  {
    return try  FfiConverterSequenceTypeEnrollmentChangeEvent.lift(try rustCallWithError(FfiConverterTypeNimbusError_lift) {
    uniffi_nimbus_fn_method_nimbusclient_set_global_user_participation(self.uniffiClonePointer(),
        FfiConverterBool.lower(optIn),$0
    )
})
}
    
open func unenrollForGeckoPref(prefState: GeckoPrefState, prefUnenrollReason: PrefUnenrollReason)throws  -> [EnrollmentChangeEvent]  {
    return try  FfiConverterSequenceTypeEnrollmentChangeEvent.lift(try rustCallWithError(FfiConverterTypeNimbusError_lift) {
    uniffi_nimbus_fn_method_nimbusclient_unenroll_for_gecko_pref(self.uniffiClonePointer(),
        FfiConverterTypeGeckoPrefState_lower(prefState),
        FfiConverterTypePrefUnenrollReason_lower(prefUnenrollReason),$0
    )
})
}
    

}


#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public struct FfiConverterTypeNimbusClient: FfiConverter {

    typealias FfiType = UnsafeMutableRawPointer
    typealias SwiftType = NimbusClient

    public static func lift(_ pointer: UnsafeMutableRawPointer) throws -> NimbusClient {
        return NimbusClient(unsafeFromRawPointer: pointer)
    }

    public static func lower(_ value: NimbusClient) -> UnsafeMutableRawPointer {
        return value.uniffiClonePointer()
    }

    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> NimbusClient {
        let v: UInt64 = try readInt(&buf)
        // The Rust code won't compile if a pointer won't fit in a UInt64.
        // We have to go via `UInt` because that's the thing that's the size of a pointer.
        let ptr = UnsafeMutableRawPointer(bitPattern: UInt(truncatingIfNeeded: v))
        if (ptr == nil) {
            throw UniffiInternalError.unexpectedNullPointer
        }
        return try lift(ptr!)
    }

    public static func write(_ value: NimbusClient, into buf: inout [UInt8]) {
        // This fiddling is because `Int` is the thing that's the same size as a pointer.
        // The Rust code won't compile if a pointer won't fit in a `UInt64`.
        writeInt(&buf, UInt64(bitPattern: Int64(Int(bitPattern: lower(value)))))
    }
}


#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeNimbusClient_lift(_ pointer: UnsafeMutableRawPointer) throws -> NimbusClient {
    return try FfiConverterTypeNimbusClient.lift(pointer)
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeNimbusClient_lower(_ value: NimbusClient) -> UnsafeMutableRawPointer {
    return FfiConverterTypeNimbusClient.lower(value)
}






public protocol NimbusStringHelperProtocol: AnyObject {
    
    /**
     * Generates an optional UUID to be passed into the `string_format` method.
     * If the return is not null, then it should be recorded with Glean as a UuidMetricType.
     */
    func getUuid(template: String)  -> String?
    
    /**
     * Take the given template and find patterns that match the regular expression `{\w+}`.
     * Any matches are used as keys into the application context, the `additional_context` or the special case `uuid`.
     */
    func stringFormat(template: String, uuid: String?)  -> String
    
}
open class NimbusStringHelper: NimbusStringHelperProtocol, @unchecked Sendable {
    fileprivate let pointer: UnsafeMutableRawPointer!

    /// Used to instantiate a [FFIObject] without an actual pointer, for fakes in tests, mostly.
#if swift(>=5.8)
    @_documentation(visibility: private)
#endif
    public struct NoPointer {
        public init() {}
    }

    // TODO: We'd like this to be `private` but for Swifty reasons,
    // we can't implement `FfiConverter` without making this `required` and we can't
    // make it `required` without making it `public`.
    required public init(unsafeFromRawPointer pointer: UnsafeMutableRawPointer) {
        self.pointer = pointer
    }

    // This constructor can be used to instantiate a fake object.
    // - Parameter noPointer: Placeholder value so we can have a constructor separate from the default empty one that may be implemented for classes extending [FFIObject].
    //
    // - Warning:
    //     Any object instantiated with this constructor cannot be passed to an actual Rust-backed object. Since there isn't a backing [Pointer] the FFI lower functions will crash.
#if swift(>=5.8)
    @_documentation(visibility: private)
#endif
    public init(noPointer: NoPointer) {
        self.pointer = nil
    }

#if swift(>=5.8)
    @_documentation(visibility: private)
#endif
    public func uniffiClonePointer() -> UnsafeMutableRawPointer {
        return try! rustCall { uniffi_nimbus_fn_clone_nimbusstringhelper(self.pointer, $0) }
    }
    // No primary constructor declared for this class.

    deinit {
        guard let pointer = pointer else {
            return
        }

        try! rustCall { uniffi_nimbus_fn_free_nimbusstringhelper(pointer, $0) }
    }

    

    
    /**
     * Generates an optional UUID to be passed into the `string_format` method.
     * If the return is not null, then it should be recorded with Glean as a UuidMetricType.
     */
open func getUuid(template: String) -> String?  {
    return try!  FfiConverterOptionString.lift(try! rustCall() {
    uniffi_nimbus_fn_method_nimbusstringhelper_get_uuid(self.uniffiClonePointer(),
        FfiConverterString.lower(template),$0
    )
})
}
    
    /**
     * Take the given template and find patterns that match the regular expression `{\w+}`.
     * Any matches are used as keys into the application context, the `additional_context` or the special case `uuid`.
     */
open func stringFormat(template: String, uuid: String? = nil) -> String  {
    return try!  FfiConverterString.lift(try! rustCall() {
    uniffi_nimbus_fn_method_nimbusstringhelper_string_format(self.uniffiClonePointer(),
        FfiConverterString.lower(template),
        FfiConverterOptionString.lower(uuid),$0
    )
})
}
    

}


#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public struct FfiConverterTypeNimbusStringHelper: FfiConverter {

    typealias FfiType = UnsafeMutableRawPointer
    typealias SwiftType = NimbusStringHelper

    public static func lift(_ pointer: UnsafeMutableRawPointer) throws -> NimbusStringHelper {
        return NimbusStringHelper(unsafeFromRawPointer: pointer)
    }

    public static func lower(_ value: NimbusStringHelper) -> UnsafeMutableRawPointer {
        return value.uniffiClonePointer()
    }

    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> NimbusStringHelper {
        let v: UInt64 = try readInt(&buf)
        // The Rust code won't compile if a pointer won't fit in a UInt64.
        // We have to go via `UInt` because that's the thing that's the size of a pointer.
        let ptr = UnsafeMutableRawPointer(bitPattern: UInt(truncatingIfNeeded: v))
        if (ptr == nil) {
            throw UniffiInternalError.unexpectedNullPointer
        }
        return try lift(ptr!)
    }

    public static func write(_ value: NimbusStringHelper, into buf: inout [UInt8]) {
        // This fiddling is because `Int` is the thing that's the same size as a pointer.
        // The Rust code won't compile if a pointer won't fit in a `UInt64`.
        writeInt(&buf, UInt64(bitPattern: Int64(Int(bitPattern: lower(value)))))
    }
}


#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeNimbusStringHelper_lift(_ pointer: UnsafeMutableRawPointer) throws -> NimbusStringHelper {
    return try FfiConverterTypeNimbusStringHelper.lift(pointer)
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeNimbusStringHelper_lower(_ value: NimbusStringHelper) -> UnsafeMutableRawPointer {
    return FfiConverterTypeNimbusStringHelper.lower(value)
}






public protocol NimbusTargetingHelperProtocol: AnyObject {
    
    /**
     * Execute the given jexl expression and evaluate against the existing targeting parameters and context passed to
     * the helper at construction.
     */
    func evalJexl(expression: String) throws  -> Bool
    
}
open class NimbusTargetingHelper: NimbusTargetingHelperProtocol, @unchecked Sendable {
    fileprivate let pointer: UnsafeMutableRawPointer!

    /// Used to instantiate a [FFIObject] without an actual pointer, for fakes in tests, mostly.
#if swift(>=5.8)
    @_documentation(visibility: private)
#endif
    public struct NoPointer {
        public init() {}
    }

    // TODO: We'd like this to be `private` but for Swifty reasons,
    // we can't implement `FfiConverter` without making this `required` and we can't
    // make it `required` without making it `public`.
    required public init(unsafeFromRawPointer pointer: UnsafeMutableRawPointer) {
        self.pointer = pointer
    }

    // This constructor can be used to instantiate a fake object.
    // - Parameter noPointer: Placeholder value so we can have a constructor separate from the default empty one that may be implemented for classes extending [FFIObject].
    //
    // - Warning:
    //     Any object instantiated with this constructor cannot be passed to an actual Rust-backed object. Since there isn't a backing [Pointer] the FFI lower functions will crash.
#if swift(>=5.8)
    @_documentation(visibility: private)
#endif
    public init(noPointer: NoPointer) {
        self.pointer = nil
    }

#if swift(>=5.8)
    @_documentation(visibility: private)
#endif
    public func uniffiClonePointer() -> UnsafeMutableRawPointer {
        return try! rustCall { uniffi_nimbus_fn_clone_nimbustargetinghelper(self.pointer, $0) }
    }
    // No primary constructor declared for this class.

    deinit {
        guard let pointer = pointer else {
            return
        }

        try! rustCall { uniffi_nimbus_fn_free_nimbustargetinghelper(pointer, $0) }
    }

    

    
    /**
     * Execute the given jexl expression and evaluate against the existing targeting parameters and context passed to
     * the helper at construction.
     */
open func evalJexl(expression: String)throws  -> Bool  {
    return try  FfiConverterBool.lift(try rustCallWithError(FfiConverterTypeNimbusError_lift) {
    uniffi_nimbus_fn_method_nimbustargetinghelper_eval_jexl(self.uniffiClonePointer(),
        FfiConverterString.lower(expression),$0
    )
})
}
    

}


#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public struct FfiConverterTypeNimbusTargetingHelper: FfiConverter {

    typealias FfiType = UnsafeMutableRawPointer
    typealias SwiftType = NimbusTargetingHelper

    public static func lift(_ pointer: UnsafeMutableRawPointer) throws -> NimbusTargetingHelper {
        return NimbusTargetingHelper(unsafeFromRawPointer: pointer)
    }

    public static func lower(_ value: NimbusTargetingHelper) -> UnsafeMutableRawPointer {
        return value.uniffiClonePointer()
    }

    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> NimbusTargetingHelper {
        let v: UInt64 = try readInt(&buf)
        // The Rust code won't compile if a pointer won't fit in a UInt64.
        // We have to go via `UInt` because that's the thing that's the size of a pointer.
        let ptr = UnsafeMutableRawPointer(bitPattern: UInt(truncatingIfNeeded: v))
        if (ptr == nil) {
            throw UniffiInternalError.unexpectedNullPointer
        }
        return try lift(ptr!)
    }

    public static func write(_ value: NimbusTargetingHelper, into buf: inout [UInt8]) {
        // This fiddling is because `Int` is the thing that's the same size as a pointer.
        // The Rust code won't compile if a pointer won't fit in a `UInt64`.
        writeInt(&buf, UInt64(bitPattern: Int64(Int(bitPattern: lower(value)))))
    }
}


#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeNimbusTargetingHelper_lift(_ pointer: UnsafeMutableRawPointer) throws -> NimbusTargetingHelper {
    return try FfiConverterTypeNimbusTargetingHelper.lift(pointer)
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeNimbusTargetingHelper_lower(_ value: NimbusTargetingHelper) -> UnsafeMutableRawPointer {
    return FfiConverterTypeNimbusTargetingHelper.lower(value)
}






public protocol RecordedContext: AnyObject {
    
    func getEventQueries()  -> [String: String]
    
    func record() 
    
    func setEventQueryValues(eventQueryValues: [String: Double]) 
    
    func toJson()  -> JsonObject
    
}
open class RecordedContextImpl: RecordedContext, @unchecked Sendable {
    fileprivate let pointer: UnsafeMutableRawPointer!

    /// Used to instantiate a [FFIObject] without an actual pointer, for fakes in tests, mostly.
#if swift(>=5.8)
    @_documentation(visibility: private)
#endif
    public struct NoPointer {
        public init() {}
    }

    // TODO: We'd like this to be `private` but for Swifty reasons,
    // we can't implement `FfiConverter` without making this `required` and we can't
    // make it `required` without making it `public`.
    required public init(unsafeFromRawPointer pointer: UnsafeMutableRawPointer) {
        self.pointer = pointer
    }

    // This constructor can be used to instantiate a fake object.
    // - Parameter noPointer: Placeholder value so we can have a constructor separate from the default empty one that may be implemented for classes extending [FFIObject].
    //
    // - Warning:
    //     Any object instantiated with this constructor cannot be passed to an actual Rust-backed object. Since there isn't a backing [Pointer] the FFI lower functions will crash.
#if swift(>=5.8)
    @_documentation(visibility: private)
#endif
    public init(noPointer: NoPointer) {
        self.pointer = nil
    }

#if swift(>=5.8)
    @_documentation(visibility: private)
#endif
    public func uniffiClonePointer() -> UnsafeMutableRawPointer {
        return try! rustCall { uniffi_nimbus_fn_clone_recordedcontext(self.pointer, $0) }
    }
    // No primary constructor declared for this class.

    deinit {
        guard let pointer = pointer else {
            return
        }

        try! rustCall { uniffi_nimbus_fn_free_recordedcontext(pointer, $0) }
    }

    

    
open func getEventQueries() -> [String: String]  {
    return try!  FfiConverterDictionaryStringString.lift(try! rustCall() {
    uniffi_nimbus_fn_method_recordedcontext_get_event_queries(self.uniffiClonePointer(),$0
    )
})
}
    
open func record()  {try! rustCall() {
    uniffi_nimbus_fn_method_recordedcontext_record(self.uniffiClonePointer(),$0
    )
}
}
    
open func setEventQueryValues(eventQueryValues: [String: Double])  {try! rustCall() {
    uniffi_nimbus_fn_method_recordedcontext_set_event_query_values(self.uniffiClonePointer(),
        FfiConverterDictionaryStringDouble.lower(eventQueryValues),$0
    )
}
}
    
open func toJson() -> JsonObject  {
    return try!  FfiConverterTypeJsonObject_lift(try! rustCall() {
    uniffi_nimbus_fn_method_recordedcontext_to_json(self.uniffiClonePointer(),$0
    )
})
}
    

}
// Magic number for the Rust proxy to call using the same mechanism as every other method,
// to free the callback once it's dropped by Rust.
private let IDX_CALLBACK_FREE: Int32 = 0
// Callback return codes
private let UNIFFI_CALLBACK_SUCCESS: Int32 = 0
private let UNIFFI_CALLBACK_ERROR: Int32 = 1
private let UNIFFI_CALLBACK_UNEXPECTED_ERROR: Int32 = 2

// Put the implementation in a struct so we don't pollute the top-level namespace
fileprivate struct UniffiCallbackInterfaceRecordedContext {

    // Create the VTable using a series of closures.
    // Swift automatically converts these into C callback functions.
    //
    // This creates 1-element array, since this seems to be the only way to construct a const
    // pointer that we can pass to the Rust code.
    static let vtable: [UniffiVTableCallbackInterfaceRecordedContext] = [UniffiVTableCallbackInterfaceRecordedContext(
        getEventQueries: { (
            uniffiHandle: UInt64,
            uniffiOutReturn: UnsafeMutablePointer<RustBuffer>,
            uniffiCallStatus: UnsafeMutablePointer<RustCallStatus>
        ) in
            let makeCall = {
                () throws -> [String: String] in
                guard let uniffiObj = try? FfiConverterTypeRecordedContext.handleMap.get(handle: uniffiHandle) else {
                    throw UniffiInternalError.unexpectedStaleHandle
                }
                return uniffiObj.getEventQueries(
                )
            }

            
            let writeReturn = { uniffiOutReturn.pointee = FfiConverterDictionaryStringString.lower($0) }
            uniffiTraitInterfaceCall(
                callStatus: uniffiCallStatus,
                makeCall: makeCall,
                writeReturn: writeReturn
            )
        },
        record: { (
            uniffiHandle: UInt64,
            uniffiOutReturn: UnsafeMutableRawPointer,
            uniffiCallStatus: UnsafeMutablePointer<RustCallStatus>
        ) in
            let makeCall = {
                () throws -> () in
                guard let uniffiObj = try? FfiConverterTypeRecordedContext.handleMap.get(handle: uniffiHandle) else {
                    throw UniffiInternalError.unexpectedStaleHandle
                }
                return uniffiObj.record(
                )
            }

            
            let writeReturn = { () }
            uniffiTraitInterfaceCall(
                callStatus: uniffiCallStatus,
                makeCall: makeCall,
                writeReturn: writeReturn
            )
        },
        setEventQueryValues: { (
            uniffiHandle: UInt64,
            eventQueryValues: RustBuffer,
            uniffiOutReturn: UnsafeMutableRawPointer,
            uniffiCallStatus: UnsafeMutablePointer<RustCallStatus>
        ) in
            let makeCall = {
                () throws -> () in
                guard let uniffiObj = try? FfiConverterTypeRecordedContext.handleMap.get(handle: uniffiHandle) else {
                    throw UniffiInternalError.unexpectedStaleHandle
                }
                return uniffiObj.setEventQueryValues(
                     eventQueryValues: try FfiConverterDictionaryStringDouble.lift(eventQueryValues)
                )
            }

            
            let writeReturn = { () }
            uniffiTraitInterfaceCall(
                callStatus: uniffiCallStatus,
                makeCall: makeCall,
                writeReturn: writeReturn
            )
        },
        toJson: { (
            uniffiHandle: UInt64,
            uniffiOutReturn: UnsafeMutablePointer<RustBuffer>,
            uniffiCallStatus: UnsafeMutablePointer<RustCallStatus>
        ) in
            let makeCall = {
                () throws -> JsonObject in
                guard let uniffiObj = try? FfiConverterTypeRecordedContext.handleMap.get(handle: uniffiHandle) else {
                    throw UniffiInternalError.unexpectedStaleHandle
                }
                return uniffiObj.toJson(
                )
            }

            
            let writeReturn = { uniffiOutReturn.pointee = FfiConverterTypeJsonObject_lower($0) }
            uniffiTraitInterfaceCall(
                callStatus: uniffiCallStatus,
                makeCall: makeCall,
                writeReturn: writeReturn
            )
        },
        uniffiFree: { (uniffiHandle: UInt64) -> () in
            let result = try? FfiConverterTypeRecordedContext.handleMap.remove(handle: uniffiHandle)
            if result == nil {
                print("Uniffi callback interface RecordedContext: handle missing in uniffiFree")
            }
        }
    )]
}

private func uniffiCallbackInitRecordedContext() {
    uniffi_nimbus_fn_init_callback_vtable_recordedcontext(UniffiCallbackInterfaceRecordedContext.vtable)
}


#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public struct FfiConverterTypeRecordedContext: FfiConverter {
    fileprivate static let handleMap = UniffiHandleMap<RecordedContext>()

    typealias FfiType = UnsafeMutableRawPointer
    typealias SwiftType = RecordedContext

    public static func lift(_ pointer: UnsafeMutableRawPointer) throws -> RecordedContext {
        return RecordedContextImpl(unsafeFromRawPointer: pointer)
    }

    public static func lower(_ value: RecordedContext) -> UnsafeMutableRawPointer {
        guard let ptr = UnsafeMutableRawPointer(bitPattern: UInt(truncatingIfNeeded: handleMap.insert(obj: value))) else {
            fatalError("Cast to UnsafeMutableRawPointer failed")
        }
        return ptr
    }

    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> RecordedContext {
        let v: UInt64 = try readInt(&buf)
        // The Rust code won't compile if a pointer won't fit in a UInt64.
        // We have to go via `UInt` because that's the thing that's the size of a pointer.
        let ptr = UnsafeMutableRawPointer(bitPattern: UInt(truncatingIfNeeded: v))
        if (ptr == nil) {
            throw UniffiInternalError.unexpectedNullPointer
        }
        return try lift(ptr!)
    }

    public static func write(_ value: RecordedContext, into buf: inout [UInt8]) {
        // This fiddling is because `Int` is the thing that's the same size as a pointer.
        // The Rust code won't compile if a pointer won't fit in a `UInt64`.
        writeInt(&buf, UInt64(bitPattern: Int64(Int(bitPattern: lower(value)))))
    }
}


#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeRecordedContext_lift(_ pointer: UnsafeMutableRawPointer) throws -> RecordedContext {
    return try FfiConverterTypeRecordedContext.lift(pointer)
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeRecordedContext_lower(_ value: RecordedContext) -> UnsafeMutableRawPointer {
    return FfiConverterTypeRecordedContext.lower(value)
}




public struct AppContext {
    public var appName: String
    public var appId: String
    public var channel: String
    public var appVersion: String?
    public var appBuild: String?
    public var architecture: String?
    public var deviceManufacturer: String?
    public var deviceModel: String?
    public var locale: String?
    public var os: String?
    public var osVersion: String?
    public var androidSdkVersion: String?
    public var debugTag: String?
    public var installationDate: Int64?
    public var homeDirectory: String?
    public var customTargetingAttributes: JsonObject?

    // Default memberwise initializers are never public by default, so we
    // declare one manually.
    public init(appName: String, appId: String, channel: String, appVersion: String?, appBuild: String?, architecture: String?, deviceManufacturer: String?, deviceModel: String?, locale: String?, os: String?, osVersion: String?, androidSdkVersion: String?, debugTag: String?, installationDate: Int64?, homeDirectory: String?, customTargetingAttributes: JsonObject?) {
        self.appName = appName
        self.appId = appId
        self.channel = channel
        self.appVersion = appVersion
        self.appBuild = appBuild
        self.architecture = architecture
        self.deviceManufacturer = deviceManufacturer
        self.deviceModel = deviceModel
        self.locale = locale
        self.os = os
        self.osVersion = osVersion
        self.androidSdkVersion = androidSdkVersion
        self.debugTag = debugTag
        self.installationDate = installationDate
        self.homeDirectory = homeDirectory
        self.customTargetingAttributes = customTargetingAttributes
    }
}

#if compiler(>=6)
extension AppContext: Sendable {}
#endif


extension AppContext: Equatable, Hashable {
    public static func ==(lhs: AppContext, rhs: AppContext) -> Bool {
        if lhs.appName != rhs.appName {
            return false
        }
        if lhs.appId != rhs.appId {
            return false
        }
        if lhs.channel != rhs.channel {
            return false
        }
        if lhs.appVersion != rhs.appVersion {
            return false
        }
        if lhs.appBuild != rhs.appBuild {
            return false
        }
        if lhs.architecture != rhs.architecture {
            return false
        }
        if lhs.deviceManufacturer != rhs.deviceManufacturer {
            return false
        }
        if lhs.deviceModel != rhs.deviceModel {
            return false
        }
        if lhs.locale != rhs.locale {
            return false
        }
        if lhs.os != rhs.os {
            return false
        }
        if lhs.osVersion != rhs.osVersion {
            return false
        }
        if lhs.androidSdkVersion != rhs.androidSdkVersion {
            return false
        }
        if lhs.debugTag != rhs.debugTag {
            return false
        }
        if lhs.installationDate != rhs.installationDate {
            return false
        }
        if lhs.homeDirectory != rhs.homeDirectory {
            return false
        }
        if lhs.customTargetingAttributes != rhs.customTargetingAttributes {
            return false
        }
        return true
    }

    public func hash(into hasher: inout Hasher) {
        hasher.combine(appName)
        hasher.combine(appId)
        hasher.combine(channel)
        hasher.combine(appVersion)
        hasher.combine(appBuild)
        hasher.combine(architecture)
        hasher.combine(deviceManufacturer)
        hasher.combine(deviceModel)
        hasher.combine(locale)
        hasher.combine(os)
        hasher.combine(osVersion)
        hasher.combine(androidSdkVersion)
        hasher.combine(debugTag)
        hasher.combine(installationDate)
        hasher.combine(homeDirectory)
        hasher.combine(customTargetingAttributes)
    }
}



#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public struct FfiConverterTypeAppContext: FfiConverterRustBuffer {
    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> AppContext {
        return
            try AppContext(
                appName: FfiConverterString.read(from: &buf), 
                appId: FfiConverterString.read(from: &buf), 
                channel: FfiConverterString.read(from: &buf), 
                appVersion: FfiConverterOptionString.read(from: &buf), 
                appBuild: FfiConverterOptionString.read(from: &buf), 
                architecture: FfiConverterOptionString.read(from: &buf), 
                deviceManufacturer: FfiConverterOptionString.read(from: &buf), 
                deviceModel: FfiConverterOptionString.read(from: &buf), 
                locale: FfiConverterOptionString.read(from: &buf), 
                os: FfiConverterOptionString.read(from: &buf), 
                osVersion: FfiConverterOptionString.read(from: &buf), 
                androidSdkVersion: FfiConverterOptionString.read(from: &buf), 
                debugTag: FfiConverterOptionString.read(from: &buf), 
                installationDate: FfiConverterOptionInt64.read(from: &buf), 
                homeDirectory: FfiConverterOptionString.read(from: &buf), 
                customTargetingAttributes: FfiConverterOptionTypeJsonObject.read(from: &buf)
        )
    }

    public static func write(_ value: AppContext, into buf: inout [UInt8]) {
        FfiConverterString.write(value.appName, into: &buf)
        FfiConverterString.write(value.appId, into: &buf)
        FfiConverterString.write(value.channel, into: &buf)
        FfiConverterOptionString.write(value.appVersion, into: &buf)
        FfiConverterOptionString.write(value.appBuild, into: &buf)
        FfiConverterOptionString.write(value.architecture, into: &buf)
        FfiConverterOptionString.write(value.deviceManufacturer, into: &buf)
        FfiConverterOptionString.write(value.deviceModel, into: &buf)
        FfiConverterOptionString.write(value.locale, into: &buf)
        FfiConverterOptionString.write(value.os, into: &buf)
        FfiConverterOptionString.write(value.osVersion, into: &buf)
        FfiConverterOptionString.write(value.androidSdkVersion, into: &buf)
        FfiConverterOptionString.write(value.debugTag, into: &buf)
        FfiConverterOptionInt64.write(value.installationDate, into: &buf)
        FfiConverterOptionString.write(value.homeDirectory, into: &buf)
        FfiConverterOptionTypeJsonObject.write(value.customTargetingAttributes, into: &buf)
    }
}


#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeAppContext_lift(_ buf: RustBuffer) throws -> AppContext {
    return try FfiConverterTypeAppContext.lift(buf)
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeAppContext_lower(_ value: AppContext) -> RustBuffer {
    return FfiConverterTypeAppContext.lower(value)
}


public struct AvailableExperiment {
    public var slug: String
    public var userFacingName: String
    public var userFacingDescription: String
    public var branches: [ExperimentBranch]
    public var referenceBranch: String?

    // Default memberwise initializers are never public by default, so we
    // declare one manually.
    public init(slug: String, userFacingName: String, userFacingDescription: String, branches: [ExperimentBranch], referenceBranch: String?) {
        self.slug = slug
        self.userFacingName = userFacingName
        self.userFacingDescription = userFacingDescription
        self.branches = branches
        self.referenceBranch = referenceBranch
    }
}

#if compiler(>=6)
extension AvailableExperiment: Sendable {}
#endif


extension AvailableExperiment: Equatable, Hashable {
    public static func ==(lhs: AvailableExperiment, rhs: AvailableExperiment) -> Bool {
        if lhs.slug != rhs.slug {
            return false
        }
        if lhs.userFacingName != rhs.userFacingName {
            return false
        }
        if lhs.userFacingDescription != rhs.userFacingDescription {
            return false
        }
        if lhs.branches != rhs.branches {
            return false
        }
        if lhs.referenceBranch != rhs.referenceBranch {
            return false
        }
        return true
    }

    public func hash(into hasher: inout Hasher) {
        hasher.combine(slug)
        hasher.combine(userFacingName)
        hasher.combine(userFacingDescription)
        hasher.combine(branches)
        hasher.combine(referenceBranch)
    }
}



#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public struct FfiConverterTypeAvailableExperiment: FfiConverterRustBuffer {
    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> AvailableExperiment {
        return
            try AvailableExperiment(
                slug: FfiConverterString.read(from: &buf), 
                userFacingName: FfiConverterString.read(from: &buf), 
                userFacingDescription: FfiConverterString.read(from: &buf), 
                branches: FfiConverterSequenceTypeExperimentBranch.read(from: &buf), 
                referenceBranch: FfiConverterOptionString.read(from: &buf)
        )
    }

    public static func write(_ value: AvailableExperiment, into buf: inout [UInt8]) {
        FfiConverterString.write(value.slug, into: &buf)
        FfiConverterString.write(value.userFacingName, into: &buf)
        FfiConverterString.write(value.userFacingDescription, into: &buf)
        FfiConverterSequenceTypeExperimentBranch.write(value.branches, into: &buf)
        FfiConverterOptionString.write(value.referenceBranch, into: &buf)
    }
}


#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeAvailableExperiment_lift(_ buf: RustBuffer) throws -> AvailableExperiment {
    return try FfiConverterTypeAvailableExperiment.lift(buf)
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeAvailableExperiment_lower(_ value: AvailableExperiment) -> RustBuffer {
    return FfiConverterTypeAvailableExperiment.lower(value)
}


public struct CalculatedAttributes {
    public var daysSinceInstall: Int32?
    public var daysSinceUpdate: Int32?
    public var language: String?
    public var region: String?

    // Default memberwise initializers are never public by default, so we
    // declare one manually.
    public init(daysSinceInstall: Int32?, daysSinceUpdate: Int32?, language: String?, region: String?) {
        self.daysSinceInstall = daysSinceInstall
        self.daysSinceUpdate = daysSinceUpdate
        self.language = language
        self.region = region
    }
}

#if compiler(>=6)
extension CalculatedAttributes: Sendable {}
#endif


extension CalculatedAttributes: Equatable, Hashable {
    public static func ==(lhs: CalculatedAttributes, rhs: CalculatedAttributes) -> Bool {
        if lhs.daysSinceInstall != rhs.daysSinceInstall {
            return false
        }
        if lhs.daysSinceUpdate != rhs.daysSinceUpdate {
            return false
        }
        if lhs.language != rhs.language {
            return false
        }
        if lhs.region != rhs.region {
            return false
        }
        return true
    }

    public func hash(into hasher: inout Hasher) {
        hasher.combine(daysSinceInstall)
        hasher.combine(daysSinceUpdate)
        hasher.combine(language)
        hasher.combine(region)
    }
}



#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public struct FfiConverterTypeCalculatedAttributes: FfiConverterRustBuffer {
    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> CalculatedAttributes {
        return
            try CalculatedAttributes(
                daysSinceInstall: FfiConverterOptionInt32.read(from: &buf), 
                daysSinceUpdate: FfiConverterOptionInt32.read(from: &buf), 
                language: FfiConverterOptionString.read(from: &buf), 
                region: FfiConverterOptionString.read(from: &buf)
        )
    }

    public static func write(_ value: CalculatedAttributes, into buf: inout [UInt8]) {
        FfiConverterOptionInt32.write(value.daysSinceInstall, into: &buf)
        FfiConverterOptionInt32.write(value.daysSinceUpdate, into: &buf)
        FfiConverterOptionString.write(value.language, into: &buf)
        FfiConverterOptionString.write(value.region, into: &buf)
    }
}


#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeCalculatedAttributes_lift(_ buf: RustBuffer) throws -> CalculatedAttributes {
    return try FfiConverterTypeCalculatedAttributes.lift(buf)
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeCalculatedAttributes_lower(_ value: CalculatedAttributes) -> RustBuffer {
    return FfiConverterTypeCalculatedAttributes.lower(value)
}


public struct EnrolledExperiment {
    public var featureIds: [String]
    public var slug: String
    public var userFacingName: String
    public var userFacingDescription: String
    public var branchSlug: String

    // Default memberwise initializers are never public by default, so we
    // declare one manually.
    public init(featureIds: [String], slug: String, userFacingName: String, userFacingDescription: String, branchSlug: String) {
        self.featureIds = featureIds
        self.slug = slug
        self.userFacingName = userFacingName
        self.userFacingDescription = userFacingDescription
        self.branchSlug = branchSlug
    }
}

#if compiler(>=6)
extension EnrolledExperiment: Sendable {}
#endif


extension EnrolledExperiment: Equatable, Hashable {
    public static func ==(lhs: EnrolledExperiment, rhs: EnrolledExperiment) -> Bool {
        if lhs.featureIds != rhs.featureIds {
            return false
        }
        if lhs.slug != rhs.slug {
            return false
        }
        if lhs.userFacingName != rhs.userFacingName {
            return false
        }
        if lhs.userFacingDescription != rhs.userFacingDescription {
            return false
        }
        if lhs.branchSlug != rhs.branchSlug {
            return false
        }
        return true
    }

    public func hash(into hasher: inout Hasher) {
        hasher.combine(featureIds)
        hasher.combine(slug)
        hasher.combine(userFacingName)
        hasher.combine(userFacingDescription)
        hasher.combine(branchSlug)
    }
}



#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public struct FfiConverterTypeEnrolledExperiment: FfiConverterRustBuffer {
    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> EnrolledExperiment {
        return
            try EnrolledExperiment(
                featureIds: FfiConverterSequenceString.read(from: &buf), 
                slug: FfiConverterString.read(from: &buf), 
                userFacingName: FfiConverterString.read(from: &buf), 
                userFacingDescription: FfiConverterString.read(from: &buf), 
                branchSlug: FfiConverterString.read(from: &buf)
        )
    }

    public static func write(_ value: EnrolledExperiment, into buf: inout [UInt8]) {
        FfiConverterSequenceString.write(value.featureIds, into: &buf)
        FfiConverterString.write(value.slug, into: &buf)
        FfiConverterString.write(value.userFacingName, into: &buf)
        FfiConverterString.write(value.userFacingDescription, into: &buf)
        FfiConverterString.write(value.branchSlug, into: &buf)
    }
}


#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeEnrolledExperiment_lift(_ buf: RustBuffer) throws -> EnrolledExperiment {
    return try FfiConverterTypeEnrolledExperiment.lift(buf)
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeEnrolledExperiment_lower(_ value: EnrolledExperiment) -> RustBuffer {
    return FfiConverterTypeEnrolledExperiment.lower(value)
}


public struct EnrollmentChangeEvent {
    public var experimentSlug: String
    public var branchSlug: String
    public var reason: String?
    public var change: EnrollmentChangeEventType

    // Default memberwise initializers are never public by default, so we
    // declare one manually.
    public init(experimentSlug: String, branchSlug: String, reason: String?, change: EnrollmentChangeEventType) {
        self.experimentSlug = experimentSlug
        self.branchSlug = branchSlug
        self.reason = reason
        self.change = change
    }
}

#if compiler(>=6)
extension EnrollmentChangeEvent: Sendable {}
#endif


extension EnrollmentChangeEvent: Equatable, Hashable {
    public static func ==(lhs: EnrollmentChangeEvent, rhs: EnrollmentChangeEvent) -> Bool {
        if lhs.experimentSlug != rhs.experimentSlug {
            return false
        }
        if lhs.branchSlug != rhs.branchSlug {
            return false
        }
        if lhs.reason != rhs.reason {
            return false
        }
        if lhs.change != rhs.change {
            return false
        }
        return true
    }

    public func hash(into hasher: inout Hasher) {
        hasher.combine(experimentSlug)
        hasher.combine(branchSlug)
        hasher.combine(reason)
        hasher.combine(change)
    }
}



#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public struct FfiConverterTypeEnrollmentChangeEvent: FfiConverterRustBuffer {
    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> EnrollmentChangeEvent {
        return
            try EnrollmentChangeEvent(
                experimentSlug: FfiConverterString.read(from: &buf), 
                branchSlug: FfiConverterString.read(from: &buf), 
                reason: FfiConverterOptionString.read(from: &buf), 
                change: FfiConverterTypeEnrollmentChangeEventType.read(from: &buf)
        )
    }

    public static func write(_ value: EnrollmentChangeEvent, into buf: inout [UInt8]) {
        FfiConverterString.write(value.experimentSlug, into: &buf)
        FfiConverterString.write(value.branchSlug, into: &buf)
        FfiConverterOptionString.write(value.reason, into: &buf)
        FfiConverterTypeEnrollmentChangeEventType.write(value.change, into: &buf)
    }
}


#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeEnrollmentChangeEvent_lift(_ buf: RustBuffer) throws -> EnrollmentChangeEvent {
    return try FfiConverterTypeEnrollmentChangeEvent.lift(buf)
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeEnrollmentChangeEvent_lower(_ value: EnrollmentChangeEvent) -> RustBuffer {
    return FfiConverterTypeEnrollmentChangeEvent.lower(value)
}


public struct EnrollmentStatusExtraDef {
    public var branch: String?
    public var conflictSlug: String?
    public var errorString: String?
    public var reason: String?
    public var slug: String?
    public var status: String?

    // Default memberwise initializers are never public by default, so we
    // declare one manually.
    public init(branch: String?, conflictSlug: String?, errorString: String?, reason: String?, slug: String?, status: String?) {
        self.branch = branch
        self.conflictSlug = conflictSlug
        self.errorString = errorString
        self.reason = reason
        self.slug = slug
        self.status = status
    }
}

#if compiler(>=6)
extension EnrollmentStatusExtraDef: Sendable {}
#endif


extension EnrollmentStatusExtraDef: Equatable, Hashable {
    public static func ==(lhs: EnrollmentStatusExtraDef, rhs: EnrollmentStatusExtraDef) -> Bool {
        if lhs.branch != rhs.branch {
            return false
        }
        if lhs.conflictSlug != rhs.conflictSlug {
            return false
        }
        if lhs.errorString != rhs.errorString {
            return false
        }
        if lhs.reason != rhs.reason {
            return false
        }
        if lhs.slug != rhs.slug {
            return false
        }
        if lhs.status != rhs.status {
            return false
        }
        return true
    }

    public func hash(into hasher: inout Hasher) {
        hasher.combine(branch)
        hasher.combine(conflictSlug)
        hasher.combine(errorString)
        hasher.combine(reason)
        hasher.combine(slug)
        hasher.combine(status)
    }
}



#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public struct FfiConverterTypeEnrollmentStatusExtraDef: FfiConverterRustBuffer {
    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> EnrollmentStatusExtraDef {
        return
            try EnrollmentStatusExtraDef(
                branch: FfiConverterOptionString.read(from: &buf), 
                conflictSlug: FfiConverterOptionString.read(from: &buf), 
                errorString: FfiConverterOptionString.read(from: &buf), 
                reason: FfiConverterOptionString.read(from: &buf), 
                slug: FfiConverterOptionString.read(from: &buf), 
                status: FfiConverterOptionString.read(from: &buf)
        )
    }

    public static func write(_ value: EnrollmentStatusExtraDef, into buf: inout [UInt8]) {
        FfiConverterOptionString.write(value.branch, into: &buf)
        FfiConverterOptionString.write(value.conflictSlug, into: &buf)
        FfiConverterOptionString.write(value.errorString, into: &buf)
        FfiConverterOptionString.write(value.reason, into: &buf)
        FfiConverterOptionString.write(value.slug, into: &buf)
        FfiConverterOptionString.write(value.status, into: &buf)
    }
}


#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeEnrollmentStatusExtraDef_lift(_ buf: RustBuffer) throws -> EnrollmentStatusExtraDef {
    return try FfiConverterTypeEnrollmentStatusExtraDef.lift(buf)
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeEnrollmentStatusExtraDef_lower(_ value: EnrollmentStatusExtraDef) -> RustBuffer {
    return FfiConverterTypeEnrollmentStatusExtraDef.lower(value)
}


public struct ExperimentBranch {
    public var slug: String
    public var ratio: Int32

    // Default memberwise initializers are never public by default, so we
    // declare one manually.
    public init(slug: String, ratio: Int32) {
        self.slug = slug
        self.ratio = ratio
    }
}

#if compiler(>=6)
extension ExperimentBranch: Sendable {}
#endif


extension ExperimentBranch: Equatable, Hashable {
    public static func ==(lhs: ExperimentBranch, rhs: ExperimentBranch) -> Bool {
        if lhs.slug != rhs.slug {
            return false
        }
        if lhs.ratio != rhs.ratio {
            return false
        }
        return true
    }

    public func hash(into hasher: inout Hasher) {
        hasher.combine(slug)
        hasher.combine(ratio)
    }
}



#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public struct FfiConverterTypeExperimentBranch: FfiConverterRustBuffer {
    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ExperimentBranch {
        return
            try ExperimentBranch(
                slug: FfiConverterString.read(from: &buf), 
                ratio: FfiConverterInt32.read(from: &buf)
        )
    }

    public static func write(_ value: ExperimentBranch, into buf: inout [UInt8]) {
        FfiConverterString.write(value.slug, into: &buf)
        FfiConverterInt32.write(value.ratio, into: &buf)
    }
}


#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeExperimentBranch_lift(_ buf: RustBuffer) throws -> ExperimentBranch {
    return try FfiConverterTypeExperimentBranch.lift(buf)
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeExperimentBranch_lower(_ value: ExperimentBranch) -> RustBuffer {
    return FfiConverterTypeExperimentBranch.lower(value)
}


public struct FeatureExposureExtraDef {
    public var branch: String?
    public var slug: String
    public var featureId: String

    // Default memberwise initializers are never public by default, so we
    // declare one manually.
    public init(branch: String?, slug: String, featureId: String) {
        self.branch = branch
        self.slug = slug
        self.featureId = featureId
    }
}

#if compiler(>=6)
extension FeatureExposureExtraDef: Sendable {}
#endif


extension FeatureExposureExtraDef: Equatable, Hashable {
    public static func ==(lhs: FeatureExposureExtraDef, rhs: FeatureExposureExtraDef) -> Bool {
        if lhs.branch != rhs.branch {
            return false
        }
        if lhs.slug != rhs.slug {
            return false
        }
        if lhs.featureId != rhs.featureId {
            return false
        }
        return true
    }

    public func hash(into hasher: inout Hasher) {
        hasher.combine(branch)
        hasher.combine(slug)
        hasher.combine(featureId)
    }
}



#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public struct FfiConverterTypeFeatureExposureExtraDef: FfiConverterRustBuffer {
    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> FeatureExposureExtraDef {
        return
            try FeatureExposureExtraDef(
                branch: FfiConverterOptionString.read(from: &buf), 
                slug: FfiConverterString.read(from: &buf), 
                featureId: FfiConverterString.read(from: &buf)
        )
    }

    public static func write(_ value: FeatureExposureExtraDef, into buf: inout [UInt8]) {
        FfiConverterOptionString.write(value.branch, into: &buf)
        FfiConverterString.write(value.slug, into: &buf)
        FfiConverterString.write(value.featureId, into: &buf)
    }
}


#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeFeatureExposureExtraDef_lift(_ buf: RustBuffer) throws -> FeatureExposureExtraDef {
    return try FfiConverterTypeFeatureExposureExtraDef.lift(buf)
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeFeatureExposureExtraDef_lower(_ value: FeatureExposureExtraDef) -> RustBuffer {
    return FfiConverterTypeFeatureExposureExtraDef.lower(value)
}


public struct GeckoPref {
    public var pref: String
    public var branch: PrefBranch

    // Default memberwise initializers are never public by default, so we
    // declare one manually.
    public init(pref: String, branch: PrefBranch) {
        self.pref = pref
        self.branch = branch
    }
}

#if compiler(>=6)
extension GeckoPref: Sendable {}
#endif


extension GeckoPref: Equatable, Hashable {
    public static func ==(lhs: GeckoPref, rhs: GeckoPref) -> Bool {
        if lhs.pref != rhs.pref {
            return false
        }
        if lhs.branch != rhs.branch {
            return false
        }
        return true
    }

    public func hash(into hasher: inout Hasher) {
        hasher.combine(pref)
        hasher.combine(branch)
    }
}



#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public struct FfiConverterTypeGeckoPref: FfiConverterRustBuffer {
    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> GeckoPref {
        return
            try GeckoPref(
                pref: FfiConverterString.read(from: &buf), 
                branch: FfiConverterTypePrefBranch.read(from: &buf)
        )
    }

    public static func write(_ value: GeckoPref, into buf: inout [UInt8]) {
        FfiConverterString.write(value.pref, into: &buf)
        FfiConverterTypePrefBranch.write(value.branch, into: &buf)
    }
}


#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeGeckoPref_lift(_ buf: RustBuffer) throws -> GeckoPref {
    return try FfiConverterTypeGeckoPref.lift(buf)
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeGeckoPref_lower(_ value: GeckoPref) -> RustBuffer {
    return FfiConverterTypeGeckoPref.lower(value)
}


public struct GeckoPrefState {
    public var geckoPref: GeckoPref
    public var geckoValue: PrefValue?
    public var enrollmentValue: PrefEnrollmentData?
    public var isUserSet: Bool

    // Default memberwise initializers are never public by default, so we
    // declare one manually.
    public init(geckoPref: GeckoPref, geckoValue: PrefValue?, enrollmentValue: PrefEnrollmentData?, isUserSet: Bool) {
        self.geckoPref = geckoPref
        self.geckoValue = geckoValue
        self.enrollmentValue = enrollmentValue
        self.isUserSet = isUserSet
    }
}

#if compiler(>=6)
extension GeckoPrefState: Sendable {}
#endif


extension GeckoPrefState: Equatable, Hashable {
    public static func ==(lhs: GeckoPrefState, rhs: GeckoPrefState) -> Bool {
        if lhs.geckoPref != rhs.geckoPref {
            return false
        }
        if lhs.geckoValue != rhs.geckoValue {
            return false
        }
        if lhs.enrollmentValue != rhs.enrollmentValue {
            return false
        }
        if lhs.isUserSet != rhs.isUserSet {
            return false
        }
        return true
    }

    public func hash(into hasher: inout Hasher) {
        hasher.combine(geckoPref)
        hasher.combine(geckoValue)
        hasher.combine(enrollmentValue)
        hasher.combine(isUserSet)
    }
}



#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public struct FfiConverterTypeGeckoPrefState: FfiConverterRustBuffer {
    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> GeckoPrefState {
        return
            try GeckoPrefState(
                geckoPref: FfiConverterTypeGeckoPref.read(from: &buf), 
                geckoValue: FfiConverterOptionTypePrefValue.read(from: &buf), 
                enrollmentValue: FfiConverterOptionTypePrefEnrollmentData.read(from: &buf), 
                isUserSet: FfiConverterBool.read(from: &buf)
        )
    }

    public static func write(_ value: GeckoPrefState, into buf: inout [UInt8]) {
        FfiConverterTypeGeckoPref.write(value.geckoPref, into: &buf)
        FfiConverterOptionTypePrefValue.write(value.geckoValue, into: &buf)
        FfiConverterOptionTypePrefEnrollmentData.write(value.enrollmentValue, into: &buf)
        FfiConverterBool.write(value.isUserSet, into: &buf)
    }
}


#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeGeckoPrefState_lift(_ buf: RustBuffer) throws -> GeckoPrefState {
    return try FfiConverterTypeGeckoPrefState.lift(buf)
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeGeckoPrefState_lower(_ value: GeckoPrefState) -> RustBuffer {
    return FfiConverterTypeGeckoPrefState.lower(value)
}


public struct MalformedFeatureConfigExtraDef {
    public var branch: String?
    public var slug: String?
    public var featureId: String
    public var part: String

    // Default memberwise initializers are never public by default, so we
    // declare one manually.
    public init(branch: String?, slug: String?, featureId: String, part: String) {
        self.branch = branch
        self.slug = slug
        self.featureId = featureId
        self.part = part
    }
}

#if compiler(>=6)
extension MalformedFeatureConfigExtraDef: Sendable {}
#endif


extension MalformedFeatureConfigExtraDef: Equatable, Hashable {
    public static func ==(lhs: MalformedFeatureConfigExtraDef, rhs: MalformedFeatureConfigExtraDef) -> Bool {
        if lhs.branch != rhs.branch {
            return false
        }
        if lhs.slug != rhs.slug {
            return false
        }
        if lhs.featureId != rhs.featureId {
            return false
        }
        if lhs.part != rhs.part {
            return false
        }
        return true
    }

    public func hash(into hasher: inout Hasher) {
        hasher.combine(branch)
        hasher.combine(slug)
        hasher.combine(featureId)
        hasher.combine(part)
    }
}



#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public struct FfiConverterTypeMalformedFeatureConfigExtraDef: FfiConverterRustBuffer {
    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> MalformedFeatureConfigExtraDef {
        return
            try MalformedFeatureConfigExtraDef(
                branch: FfiConverterOptionString.read(from: &buf), 
                slug: FfiConverterOptionString.read(from: &buf), 
                featureId: FfiConverterString.read(from: &buf), 
                part: FfiConverterString.read(from: &buf)
        )
    }

    public static func write(_ value: MalformedFeatureConfigExtraDef, into buf: inout [UInt8]) {
        FfiConverterOptionString.write(value.branch, into: &buf)
        FfiConverterOptionString.write(value.slug, into: &buf)
        FfiConverterString.write(value.featureId, into: &buf)
        FfiConverterString.write(value.part, into: &buf)
    }
}


#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeMalformedFeatureConfigExtraDef_lift(_ buf: RustBuffer) throws -> MalformedFeatureConfigExtraDef {
    return try FfiConverterTypeMalformedFeatureConfigExtraDef.lift(buf)
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeMalformedFeatureConfigExtraDef_lower(_ value: MalformedFeatureConfigExtraDef) -> RustBuffer {
    return FfiConverterTypeMalformedFeatureConfigExtraDef.lower(value)
}


public struct PrefEnrollmentData {
    public var prefValue: PrefValue
    public var featureId: String
    public var variable: String

    // Default memberwise initializers are never public by default, so we
    // declare one manually.
    public init(prefValue: PrefValue, featureId: String, variable: String) {
        self.prefValue = prefValue
        self.featureId = featureId
        self.variable = variable
    }
}

#if compiler(>=6)
extension PrefEnrollmentData: Sendable {}
#endif


extension PrefEnrollmentData: Equatable, Hashable {
    public static func ==(lhs: PrefEnrollmentData, rhs: PrefEnrollmentData) -> Bool {
        if lhs.prefValue != rhs.prefValue {
            return false
        }
        if lhs.featureId != rhs.featureId {
            return false
        }
        if lhs.variable != rhs.variable {
            return false
        }
        return true
    }

    public func hash(into hasher: inout Hasher) {
        hasher.combine(prefValue)
        hasher.combine(featureId)
        hasher.combine(variable)
    }
}



#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public struct FfiConverterTypePrefEnrollmentData: FfiConverterRustBuffer {
    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PrefEnrollmentData {
        return
            try PrefEnrollmentData(
                prefValue: FfiConverterTypePrefValue.read(from: &buf), 
                featureId: FfiConverterString.read(from: &buf), 
                variable: FfiConverterString.read(from: &buf)
        )
    }

    public static func write(_ value: PrefEnrollmentData, into buf: inout [UInt8]) {
        FfiConverterTypePrefValue.write(value.prefValue, into: &buf)
        FfiConverterString.write(value.featureId, into: &buf)
        FfiConverterString.write(value.variable, into: &buf)
    }
}


#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypePrefEnrollmentData_lift(_ buf: RustBuffer) throws -> PrefEnrollmentData {
    return try FfiConverterTypePrefEnrollmentData.lift(buf)
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypePrefEnrollmentData_lower(_ value: PrefEnrollmentData) -> RustBuffer {
    return FfiConverterTypePrefEnrollmentData.lower(value)
}

// Note that we don't yet support `indirect` for enums.
// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion.

public enum EnrollmentChangeEventType {
    
    case enrollment
    case enrollFailed
    case disqualification
    case unenrollment
    case unenrollFailed
}


#if compiler(>=6)
extension EnrollmentChangeEventType: Sendable {}
#endif

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public struct FfiConverterTypeEnrollmentChangeEventType: FfiConverterRustBuffer {
    typealias SwiftType = EnrollmentChangeEventType

    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> EnrollmentChangeEventType {
        let variant: Int32 = try readInt(&buf)
        switch variant {
        
        case 1: return .enrollment
        
        case 2: return .enrollFailed
        
        case 3: return .disqualification
        
        case 4: return .unenrollment
        
        case 5: return .unenrollFailed
        
        default: throw UniffiInternalError.unexpectedEnumCase
        }
    }

    public static func write(_ value: EnrollmentChangeEventType, into buf: inout [UInt8]) {
        switch value {
        
        
        case .enrollment:
            writeInt(&buf, Int32(1))
        
        
        case .enrollFailed:
            writeInt(&buf, Int32(2))
        
        
        case .disqualification:
            writeInt(&buf, Int32(3))
        
        
        case .unenrollment:
            writeInt(&buf, Int32(4))
        
        
        case .unenrollFailed:
            writeInt(&buf, Int32(5))
        
        }
    }
}


#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeEnrollmentChangeEventType_lift(_ buf: RustBuffer) throws -> EnrollmentChangeEventType {
    return try FfiConverterTypeEnrollmentChangeEventType.lift(buf)
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeEnrollmentChangeEventType_lower(_ value: EnrollmentChangeEventType) -> RustBuffer {
    return FfiConverterTypeEnrollmentChangeEventType.lower(value)
}


extension EnrollmentChangeEventType: Equatable, Hashable {}




public enum NimbusError {

    
    
    case InvalidPersistedData(message: String)
    
    case RkvError(message: String)
    
    case IoError(message: String)
    
    case JsonError(message: String)
    
    case EvaluationError(message: String)
    
    case InvalidExpression(message: String)
    
    case InvalidFraction(message: String)
    
    case TryFromSliceError(message: String)
    
    case EmptyRatiosError(message: String)
    
    case OutOfBoundsError(message: String)
    
    case UrlParsingError(message: String)
    
    case UuidError(message: String)
    
    case InvalidExperimentFormat(message: String)
    
    case InvalidPath(message: String)
    
    case InternalError(message: String)
    
    case NoSuchExperiment(message: String)
    
    case NoSuchBranch(message: String)
    
    case DatabaseNotReady(message: String)
    
    case VersionParsingError(message: String)
    
    case BehaviorError(message: String)
    
    case TryFromIntError(message: String)
    
    case ParseIntError(message: String)
    
    case TransformParameterError(message: String)
    
    case ClientError(message: String)
    
    case UniFfiCallbackError(message: String)
    
    case RegexError(message: String)
    
}


#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public struct FfiConverterTypeNimbusError: FfiConverterRustBuffer {
    typealias SwiftType = NimbusError

    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> NimbusError {
        let variant: Int32 = try readInt(&buf)
        switch variant {

        

        
        case 1: return .InvalidPersistedData(
            message: try FfiConverterString.read(from: &buf)
        )
        
        case 2: return .RkvError(
            message: try FfiConverterString.read(from: &buf)
        )
        
        case 3: return .IoError(
            message: try FfiConverterString.read(from: &buf)
        )
        
        case 4: return .JsonError(
            message: try FfiConverterString.read(from: &buf)
        )
        
        case 5: return .EvaluationError(
            message: try FfiConverterString.read(from: &buf)
        )
        
        case 6: return .InvalidExpression(
            message: try FfiConverterString.read(from: &buf)
        )
        
        case 7: return .InvalidFraction(
            message: try FfiConverterString.read(from: &buf)
        )
        
        case 8: return .TryFromSliceError(
            message: try FfiConverterString.read(from: &buf)
        )
        
        case 9: return .EmptyRatiosError(
            message: try FfiConverterString.read(from: &buf)
        )
        
        case 10: return .OutOfBoundsError(
            message: try FfiConverterString.read(from: &buf)
        )
        
        case 11: return .UrlParsingError(
            message: try FfiConverterString.read(from: &buf)
        )
        
        case 12: return .UuidError(
            message: try FfiConverterString.read(from: &buf)
        )
        
        case 13: return .InvalidExperimentFormat(
            message: try FfiConverterString.read(from: &buf)
        )
        
        case 14: return .InvalidPath(
            message: try FfiConverterString.read(from: &buf)
        )
        
        case 15: return .InternalError(
            message: try FfiConverterString.read(from: &buf)
        )
        
        case 16: return .NoSuchExperiment(
            message: try FfiConverterString.read(from: &buf)
        )
        
        case 17: return .NoSuchBranch(
            message: try FfiConverterString.read(from: &buf)
        )
        
        case 18: return .DatabaseNotReady(
            message: try FfiConverterString.read(from: &buf)
        )
        
        case 19: return .VersionParsingError(
            message: try FfiConverterString.read(from: &buf)
        )
        
        case 20: return .BehaviorError(
            message: try FfiConverterString.read(from: &buf)
        )
        
        case 21: return .TryFromIntError(
            message: try FfiConverterString.read(from: &buf)
        )
        
        case 22: return .ParseIntError(
            message: try FfiConverterString.read(from: &buf)
        )
        
        case 23: return .TransformParameterError(
            message: try FfiConverterString.read(from: &buf)
        )
        
        case 24: return .ClientError(
            message: try FfiConverterString.read(from: &buf)
        )
        
        case 25: return .UniFfiCallbackError(
            message: try FfiConverterString.read(from: &buf)
        )
        
        case 26: return .RegexError(
            message: try FfiConverterString.read(from: &buf)
        )
        

        default: throw UniffiInternalError.unexpectedEnumCase
        }
    }

    public static func write(_ value: NimbusError, into buf: inout [UInt8]) {
        switch value {

        

        
        case .InvalidPersistedData(_ /* message is ignored*/):
            writeInt(&buf, Int32(1))
        case .RkvError(_ /* message is ignored*/):
            writeInt(&buf, Int32(2))
        case .IoError(_ /* message is ignored*/):
            writeInt(&buf, Int32(3))
        case .JsonError(_ /* message is ignored*/):
            writeInt(&buf, Int32(4))
        case .EvaluationError(_ /* message is ignored*/):
            writeInt(&buf, Int32(5))
        case .InvalidExpression(_ /* message is ignored*/):
            writeInt(&buf, Int32(6))
        case .InvalidFraction(_ /* message is ignored*/):
            writeInt(&buf, Int32(7))
        case .TryFromSliceError(_ /* message is ignored*/):
            writeInt(&buf, Int32(8))
        case .EmptyRatiosError(_ /* message is ignored*/):
            writeInt(&buf, Int32(9))
        case .OutOfBoundsError(_ /* message is ignored*/):
            writeInt(&buf, Int32(10))
        case .UrlParsingError(_ /* message is ignored*/):
            writeInt(&buf, Int32(11))
        case .UuidError(_ /* message is ignored*/):
            writeInt(&buf, Int32(12))
        case .InvalidExperimentFormat(_ /* message is ignored*/):
            writeInt(&buf, Int32(13))
        case .InvalidPath(_ /* message is ignored*/):
            writeInt(&buf, Int32(14))
        case .InternalError(_ /* message is ignored*/):
            writeInt(&buf, Int32(15))
        case .NoSuchExperiment(_ /* message is ignored*/):
            writeInt(&buf, Int32(16))
        case .NoSuchBranch(_ /* message is ignored*/):
            writeInt(&buf, Int32(17))
        case .DatabaseNotReady(_ /* message is ignored*/):
            writeInt(&buf, Int32(18))
        case .VersionParsingError(_ /* message is ignored*/):
            writeInt(&buf, Int32(19))
        case .BehaviorError(_ /* message is ignored*/):
            writeInt(&buf, Int32(20))
        case .TryFromIntError(_ /* message is ignored*/):
            writeInt(&buf, Int32(21))
        case .ParseIntError(_ /* message is ignored*/):
            writeInt(&buf, Int32(22))
        case .TransformParameterError(_ /* message is ignored*/):
            writeInt(&buf, Int32(23))
        case .ClientError(_ /* message is ignored*/):
            writeInt(&buf, Int32(24))
        case .UniFfiCallbackError(_ /* message is ignored*/):
            writeInt(&buf, Int32(25))
        case .RegexError(_ /* message is ignored*/):
            writeInt(&buf, Int32(26))

        
        }
    }
}


#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeNimbusError_lift(_ buf: RustBuffer) throws -> NimbusError {
    return try FfiConverterTypeNimbusError.lift(buf)
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeNimbusError_lower(_ value: NimbusError) -> RustBuffer {
    return FfiConverterTypeNimbusError.lower(value)
}


extension NimbusError: Equatable, Hashable {}



extension NimbusError: Foundation.LocalizedError {
    public var errorDescription: String? {
        String(reflecting: self)
    }
}


// Note that we don't yet support `indirect` for enums.
// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion.

public enum PrefBranch {
    
    case `default`
    case user
}


#if compiler(>=6)
extension PrefBranch: Sendable {}
#endif

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public struct FfiConverterTypePrefBranch: FfiConverterRustBuffer {
    typealias SwiftType = PrefBranch

    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PrefBranch {
        let variant: Int32 = try readInt(&buf)
        switch variant {
        
        case 1: return .`default`
        
        case 2: return .user
        
        default: throw UniffiInternalError.unexpectedEnumCase
        }
    }

    public static func write(_ value: PrefBranch, into buf: inout [UInt8]) {
        switch value {
        
        
        case .`default`:
            writeInt(&buf, Int32(1))
        
        
        case .user:
            writeInt(&buf, Int32(2))
        
        }
    }
}


#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypePrefBranch_lift(_ buf: RustBuffer) throws -> PrefBranch {
    return try FfiConverterTypePrefBranch.lift(buf)
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypePrefBranch_lower(_ value: PrefBranch) -> RustBuffer {
    return FfiConverterTypePrefBranch.lower(value)
}


extension PrefBranch: Equatable, Hashable {}



// Note that we don't yet support `indirect` for enums.
// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion.

public enum PrefUnenrollReason {
    
    case changed
    case failedToSet
}


#if compiler(>=6)
extension PrefUnenrollReason: Sendable {}
#endif

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public struct FfiConverterTypePrefUnenrollReason: FfiConverterRustBuffer {
    typealias SwiftType = PrefUnenrollReason

    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PrefUnenrollReason {
        let variant: Int32 = try readInt(&buf)
        switch variant {
        
        case 1: return .changed
        
        case 2: return .failedToSet
        
        default: throw UniffiInternalError.unexpectedEnumCase
        }
    }

    public static func write(_ value: PrefUnenrollReason, into buf: inout [UInt8]) {
        switch value {
        
        
        case .changed:
            writeInt(&buf, Int32(1))
        
        
        case .failedToSet:
            writeInt(&buf, Int32(2))
        
        }
    }
}


#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypePrefUnenrollReason_lift(_ buf: RustBuffer) throws -> PrefUnenrollReason {
    return try FfiConverterTypePrefUnenrollReason.lift(buf)
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypePrefUnenrollReason_lower(_ value: PrefUnenrollReason) -> RustBuffer {
    return FfiConverterTypePrefUnenrollReason.lower(value)
}


extension PrefUnenrollReason: Equatable, Hashable {}






public protocol GeckoPrefHandler: AnyObject {
    
    func getPrefsWithState()  -> [String: [String: GeckoPrefState]]
    
    func setGeckoPrefsState(newPrefsState: [GeckoPrefState]) 
    
}


// Put the implementation in a struct so we don't pollute the top-level namespace
fileprivate struct UniffiCallbackInterfaceGeckoPrefHandler {

    // Create the VTable using a series of closures.
    // Swift automatically converts these into C callback functions.
    //
    // This creates 1-element array, since this seems to be the only way to construct a const
    // pointer that we can pass to the Rust code.
    static let vtable: [UniffiVTableCallbackInterfaceGeckoPrefHandler] = [UniffiVTableCallbackInterfaceGeckoPrefHandler(
        getPrefsWithState: { (
            uniffiHandle: UInt64,
            uniffiOutReturn: UnsafeMutablePointer<RustBuffer>,
            uniffiCallStatus: UnsafeMutablePointer<RustCallStatus>
        ) in
            let makeCall = {
                () throws -> [String: [String: GeckoPrefState]] in
                guard let uniffiObj = try? FfiConverterCallbackInterfaceGeckoPrefHandler.handleMap.get(handle: uniffiHandle) else {
                    throw UniffiInternalError.unexpectedStaleHandle
                }
                return uniffiObj.getPrefsWithState(
                )
            }

            
            let writeReturn = { uniffiOutReturn.pointee = FfiConverterDictionaryStringDictionaryStringTypeGeckoPrefState.lower($0) }
            uniffiTraitInterfaceCall(
                callStatus: uniffiCallStatus,
                makeCall: makeCall,
                writeReturn: writeReturn
            )
        },
        setGeckoPrefsState: { (
            uniffiHandle: UInt64,
            newPrefsState: RustBuffer,
            uniffiOutReturn: UnsafeMutableRawPointer,
            uniffiCallStatus: UnsafeMutablePointer<RustCallStatus>
        ) in
            let makeCall = {
                () throws -> () in
                guard let uniffiObj = try? FfiConverterCallbackInterfaceGeckoPrefHandler.handleMap.get(handle: uniffiHandle) else {
                    throw UniffiInternalError.unexpectedStaleHandle
                }
                return uniffiObj.setGeckoPrefsState(
                     newPrefsState: try FfiConverterSequenceTypeGeckoPrefState.lift(newPrefsState)
                )
            }

            
            let writeReturn = { () }
            uniffiTraitInterfaceCall(
                callStatus: uniffiCallStatus,
                makeCall: makeCall,
                writeReturn: writeReturn
            )
        },
        uniffiFree: { (uniffiHandle: UInt64) -> () in
            let result = try? FfiConverterCallbackInterfaceGeckoPrefHandler.handleMap.remove(handle: uniffiHandle)
            if result == nil {
                print("Uniffi callback interface GeckoPrefHandler: handle missing in uniffiFree")
            }
        }
    )]
}

private func uniffiCallbackInitGeckoPrefHandler() {
    uniffi_nimbus_fn_init_callback_vtable_geckoprefhandler(UniffiCallbackInterfaceGeckoPrefHandler.vtable)
}

// FfiConverter protocol for callback interfaces
#if swift(>=5.8)
@_documentation(visibility: private)
#endif
fileprivate struct FfiConverterCallbackInterfaceGeckoPrefHandler {
    fileprivate static let handleMap = UniffiHandleMap<GeckoPrefHandler>()
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
extension FfiConverterCallbackInterfaceGeckoPrefHandler : FfiConverter {
    typealias SwiftType = GeckoPrefHandler
    typealias FfiType = UInt64

#if swift(>=5.8)
    @_documentation(visibility: private)
#endif
    public static func lift(_ handle: UInt64) throws -> SwiftType {
        try handleMap.get(handle: handle)
    }

#if swift(>=5.8)
    @_documentation(visibility: private)
#endif
    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType {
        let handle: UInt64 = try readInt(&buf)
        return try lift(handle)
    }

#if swift(>=5.8)
    @_documentation(visibility: private)
#endif
    public static func lower(_ v: SwiftType) -> UInt64 {
        return handleMap.insert(obj: v)
    }

#if swift(>=5.8)
    @_documentation(visibility: private)
#endif
    public static func write(_ v: SwiftType, into buf: inout [UInt8]) {
        writeInt(&buf, lower(v))
    }
}


#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterCallbackInterfaceGeckoPrefHandler_lift(_ handle: UInt64) throws -> GeckoPrefHandler {
    return try FfiConverterCallbackInterfaceGeckoPrefHandler.lift(handle)
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterCallbackInterfaceGeckoPrefHandler_lower(_ v: GeckoPrefHandler) -> UInt64 {
    return FfiConverterCallbackInterfaceGeckoPrefHandler.lower(v)
}




public protocol MetricsHandler: AnyObject {
    
    func recordEnrollmentStatuses(enrollmentStatusExtras: [EnrollmentStatusExtraDef]) 
    
    /**
     * Feature activation is the pre-cursor to feature exposure: it is defined as the first time
     * the feature configuration is asked for.
     */
    func recordFeatureActivation(event: FeatureExposureExtraDef) 
    
    func recordFeatureExposure(event: FeatureExposureExtraDef) 
    
    func recordMalformedFeatureConfig(event: MalformedFeatureConfigExtraDef) 
    
}


// Put the implementation in a struct so we don't pollute the top-level namespace
fileprivate struct UniffiCallbackInterfaceMetricsHandler {

    // Create the VTable using a series of closures.
    // Swift automatically converts these into C callback functions.
    //
    // This creates 1-element array, since this seems to be the only way to construct a const
    // pointer that we can pass to the Rust code.
    static let vtable: [UniffiVTableCallbackInterfaceMetricsHandler] = [UniffiVTableCallbackInterfaceMetricsHandler(
        recordEnrollmentStatuses: { (
            uniffiHandle: UInt64,
            enrollmentStatusExtras: RustBuffer,
            uniffiOutReturn: UnsafeMutableRawPointer,
            uniffiCallStatus: UnsafeMutablePointer<RustCallStatus>
        ) in
            let makeCall = {
                () throws -> () in
                guard let uniffiObj = try? FfiConverterCallbackInterfaceMetricsHandler.handleMap.get(handle: uniffiHandle) else {
                    throw UniffiInternalError.unexpectedStaleHandle
                }
                return uniffiObj.recordEnrollmentStatuses(
                     enrollmentStatusExtras: try FfiConverterSequenceTypeEnrollmentStatusExtraDef.lift(enrollmentStatusExtras)
                )
            }

            
            let writeReturn = { () }
            uniffiTraitInterfaceCall(
                callStatus: uniffiCallStatus,
                makeCall: makeCall,
                writeReturn: writeReturn
            )
        },
        recordFeatureActivation: { (
            uniffiHandle: UInt64,
            event: RustBuffer,
            uniffiOutReturn: UnsafeMutableRawPointer,
            uniffiCallStatus: UnsafeMutablePointer<RustCallStatus>
        ) in
            let makeCall = {
                () throws -> () in
                guard let uniffiObj = try? FfiConverterCallbackInterfaceMetricsHandler.handleMap.get(handle: uniffiHandle) else {
                    throw UniffiInternalError.unexpectedStaleHandle
                }
                return uniffiObj.recordFeatureActivation(
                     event: try FfiConverterTypeFeatureExposureExtraDef_lift(event)
                )
            }

            
            let writeReturn = { () }
            uniffiTraitInterfaceCall(
                callStatus: uniffiCallStatus,
                makeCall: makeCall,
                writeReturn: writeReturn
            )
        },
        recordFeatureExposure: { (
            uniffiHandle: UInt64,
            event: RustBuffer,
            uniffiOutReturn: UnsafeMutableRawPointer,
            uniffiCallStatus: UnsafeMutablePointer<RustCallStatus>
        ) in
            let makeCall = {
                () throws -> () in
                guard let uniffiObj = try? FfiConverterCallbackInterfaceMetricsHandler.handleMap.get(handle: uniffiHandle) else {
                    throw UniffiInternalError.unexpectedStaleHandle
                }
                return uniffiObj.recordFeatureExposure(
                     event: try FfiConverterTypeFeatureExposureExtraDef_lift(event)
                )
            }

            
            let writeReturn = { () }
            uniffiTraitInterfaceCall(
                callStatus: uniffiCallStatus,
                makeCall: makeCall,
                writeReturn: writeReturn
            )
        },
        recordMalformedFeatureConfig: { (
            uniffiHandle: UInt64,
            event: RustBuffer,
            uniffiOutReturn: UnsafeMutableRawPointer,
            uniffiCallStatus: UnsafeMutablePointer<RustCallStatus>
        ) in
            let makeCall = {
                () throws -> () in
                guard let uniffiObj = try? FfiConverterCallbackInterfaceMetricsHandler.handleMap.get(handle: uniffiHandle) else {
                    throw UniffiInternalError.unexpectedStaleHandle
                }
                return uniffiObj.recordMalformedFeatureConfig(
                     event: try FfiConverterTypeMalformedFeatureConfigExtraDef_lift(event)
                )
            }

            
            let writeReturn = { () }
            uniffiTraitInterfaceCall(
                callStatus: uniffiCallStatus,
                makeCall: makeCall,
                writeReturn: writeReturn
            )
        },
        uniffiFree: { (uniffiHandle: UInt64) -> () in
            let result = try? FfiConverterCallbackInterfaceMetricsHandler.handleMap.remove(handle: uniffiHandle)
            if result == nil {
                print("Uniffi callback interface MetricsHandler: handle missing in uniffiFree")
            }
        }
    )]
}

private func uniffiCallbackInitMetricsHandler() {
    uniffi_nimbus_fn_init_callback_vtable_metricshandler(UniffiCallbackInterfaceMetricsHandler.vtable)
}

// FfiConverter protocol for callback interfaces
#if swift(>=5.8)
@_documentation(visibility: private)
#endif
fileprivate struct FfiConverterCallbackInterfaceMetricsHandler {
    fileprivate static let handleMap = UniffiHandleMap<MetricsHandler>()
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
extension FfiConverterCallbackInterfaceMetricsHandler : FfiConverter {
    typealias SwiftType = MetricsHandler
    typealias FfiType = UInt64

#if swift(>=5.8)
    @_documentation(visibility: private)
#endif
    public static func lift(_ handle: UInt64) throws -> SwiftType {
        try handleMap.get(handle: handle)
    }

#if swift(>=5.8)
    @_documentation(visibility: private)
#endif
    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType {
        let handle: UInt64 = try readInt(&buf)
        return try lift(handle)
    }

#if swift(>=5.8)
    @_documentation(visibility: private)
#endif
    public static func lower(_ v: SwiftType) -> UInt64 {
        return handleMap.insert(obj: v)
    }

#if swift(>=5.8)
    @_documentation(visibility: private)
#endif
    public static func write(_ v: SwiftType, into buf: inout [UInt8]) {
        writeInt(&buf, lower(v))
    }
}


#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterCallbackInterfaceMetricsHandler_lift(_ handle: UInt64) throws -> MetricsHandler {
    return try FfiConverterCallbackInterfaceMetricsHandler.lift(handle)
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterCallbackInterfaceMetricsHandler_lower(_ v: MetricsHandler) -> UInt64 {
    return FfiConverterCallbackInterfaceMetricsHandler.lower(v)
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
fileprivate struct FfiConverterOptionInt32: FfiConverterRustBuffer {
    typealias SwiftType = Int32?

    public static func write(_ value: SwiftType, into buf: inout [UInt8]) {
        guard let value = value else {
            writeInt(&buf, Int8(0))
            return
        }
        writeInt(&buf, Int8(1))
        FfiConverterInt32.write(value, into: &buf)
    }

    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType {
        switch try readInt(&buf) as Int8 {
        case 0: return nil
        case 1: return try FfiConverterInt32.read(from: &buf)
        default: throw UniffiInternalError.unexpectedOptionalTag
        }
    }
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
fileprivate struct FfiConverterOptionInt64: FfiConverterRustBuffer {
    typealias SwiftType = Int64?

    public static func write(_ value: SwiftType, into buf: inout [UInt8]) {
        guard let value = value else {
            writeInt(&buf, Int8(0))
            return
        }
        writeInt(&buf, Int8(1))
        FfiConverterInt64.write(value, into: &buf)
    }

    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType {
        switch try readInt(&buf) as Int8 {
        case 0: return nil
        case 1: return try FfiConverterInt64.read(from: &buf)
        default: throw UniffiInternalError.unexpectedOptionalTag
        }
    }
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
fileprivate struct FfiConverterOptionString: FfiConverterRustBuffer {
    typealias SwiftType = String?

    public static func write(_ value: SwiftType, into buf: inout [UInt8]) {
        guard let value = value else {
            writeInt(&buf, Int8(0))
            return
        }
        writeInt(&buf, Int8(1))
        FfiConverterString.write(value, into: &buf)
    }

    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType {
        switch try readInt(&buf) as Int8 {
        case 0: return nil
        case 1: return try FfiConverterString.read(from: &buf)
        default: throw UniffiInternalError.unexpectedOptionalTag
        }
    }
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
fileprivate struct FfiConverterOptionTypeRecordedContext: FfiConverterRustBuffer {
    typealias SwiftType = RecordedContext?

    public static func write(_ value: SwiftType, into buf: inout [UInt8]) {
        guard let value = value else {
            writeInt(&buf, Int8(0))
            return
        }
        writeInt(&buf, Int8(1))
        FfiConverterTypeRecordedContext.write(value, into: &buf)
    }

    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType {
        switch try readInt(&buf) as Int8 {
        case 0: return nil
        case 1: return try FfiConverterTypeRecordedContext.read(from: &buf)
        default: throw UniffiInternalError.unexpectedOptionalTag
        }
    }
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
fileprivate struct FfiConverterOptionTypePrefEnrollmentData: FfiConverterRustBuffer {
    typealias SwiftType = PrefEnrollmentData?

    public static func write(_ value: SwiftType, into buf: inout [UInt8]) {
        guard let value = value else {
            writeInt(&buf, Int8(0))
            return
        }
        writeInt(&buf, Int8(1))
        FfiConverterTypePrefEnrollmentData.write(value, into: &buf)
    }

    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType {
        switch try readInt(&buf) as Int8 {
        case 0: return nil
        case 1: return try FfiConverterTypePrefEnrollmentData.read(from: &buf)
        default: throw UniffiInternalError.unexpectedOptionalTag
        }
    }
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
fileprivate struct FfiConverterOptionTypeRemoteSettingsConfig: FfiConverterRustBuffer {
    typealias SwiftType = RemoteSettingsConfig?

    public static func write(_ value: SwiftType, into buf: inout [UInt8]) {
        guard let value = value else {
            writeInt(&buf, Int8(0))
            return
        }
        writeInt(&buf, Int8(1))
        FfiConverterTypeRemoteSettingsConfig.write(value, into: &buf)
    }

    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType {
        switch try readInt(&buf) as Int8 {
        case 0: return nil
        case 1: return try FfiConverterTypeRemoteSettingsConfig.read(from: &buf)
        default: throw UniffiInternalError.unexpectedOptionalTag
        }
    }
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
fileprivate struct FfiConverterOptionCallbackInterfaceGeckoPrefHandler: FfiConverterRustBuffer {
    typealias SwiftType = GeckoPrefHandler?

    public static func write(_ value: SwiftType, into buf: inout [UInt8]) {
        guard let value = value else {
            writeInt(&buf, Int8(0))
            return
        }
        writeInt(&buf, Int8(1))
        FfiConverterCallbackInterfaceGeckoPrefHandler.write(value, into: &buf)
    }

    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType {
        switch try readInt(&buf) as Int8 {
        case 0: return nil
        case 1: return try FfiConverterCallbackInterfaceGeckoPrefHandler.read(from: &buf)
        default: throw UniffiInternalError.unexpectedOptionalTag
        }
    }
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
fileprivate struct FfiConverterOptionTypeJsonObject: FfiConverterRustBuffer {
    typealias SwiftType = JsonObject?

    public static func write(_ value: SwiftType, into buf: inout [UInt8]) {
        guard let value = value else {
            writeInt(&buf, Int8(0))
            return
        }
        writeInt(&buf, Int8(1))
        FfiConverterTypeJsonObject.write(value, into: &buf)
    }

    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType {
        switch try readInt(&buf) as Int8 {
        case 0: return nil
        case 1: return try FfiConverterTypeJsonObject.read(from: &buf)
        default: throw UniffiInternalError.unexpectedOptionalTag
        }
    }
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
fileprivate struct FfiConverterOptionTypePrefValue: FfiConverterRustBuffer {
    typealias SwiftType = PrefValue?

    public static func write(_ value: SwiftType, into buf: inout [UInt8]) {
        guard let value = value else {
            writeInt(&buf, Int8(0))
            return
        }
        writeInt(&buf, Int8(1))
        FfiConverterTypePrefValue.write(value, into: &buf)
    }

    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType {
        switch try readInt(&buf) as Int8 {
        case 0: return nil
        case 1: return try FfiConverterTypePrefValue.read(from: &buf)
        default: throw UniffiInternalError.unexpectedOptionalTag
        }
    }
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
fileprivate struct FfiConverterSequenceString: FfiConverterRustBuffer {
    typealias SwiftType = [String]

    public static func write(_ value: [String], into buf: inout [UInt8]) {
        let len = Int32(value.count)
        writeInt(&buf, len)
        for item in value {
            FfiConverterString.write(item, into: &buf)
        }
    }

    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [String] {
        let len: Int32 = try readInt(&buf)
        var seq = [String]()
        seq.reserveCapacity(Int(len))
        for _ in 0 ..< len {
            seq.append(try FfiConverterString.read(from: &buf))
        }
        return seq
    }
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
fileprivate struct FfiConverterSequenceTypeAvailableExperiment: FfiConverterRustBuffer {
    typealias SwiftType = [AvailableExperiment]

    public static func write(_ value: [AvailableExperiment], into buf: inout [UInt8]) {
        let len = Int32(value.count)
        writeInt(&buf, len)
        for item in value {
            FfiConverterTypeAvailableExperiment.write(item, into: &buf)
        }
    }

    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [AvailableExperiment] {
        let len: Int32 = try readInt(&buf)
        var seq = [AvailableExperiment]()
        seq.reserveCapacity(Int(len))
        for _ in 0 ..< len {
            seq.append(try FfiConverterTypeAvailableExperiment.read(from: &buf))
        }
        return seq
    }
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
fileprivate struct FfiConverterSequenceTypeEnrolledExperiment: FfiConverterRustBuffer {
    typealias SwiftType = [EnrolledExperiment]

    public static func write(_ value: [EnrolledExperiment], into buf: inout [UInt8]) {
        let len = Int32(value.count)
        writeInt(&buf, len)
        for item in value {
            FfiConverterTypeEnrolledExperiment.write(item, into: &buf)
        }
    }

    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [EnrolledExperiment] {
        let len: Int32 = try readInt(&buf)
        var seq = [EnrolledExperiment]()
        seq.reserveCapacity(Int(len))
        for _ in 0 ..< len {
            seq.append(try FfiConverterTypeEnrolledExperiment.read(from: &buf))
        }
        return seq
    }
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
fileprivate struct FfiConverterSequenceTypeEnrollmentChangeEvent: FfiConverterRustBuffer {
    typealias SwiftType = [EnrollmentChangeEvent]

    public static func write(_ value: [EnrollmentChangeEvent], into buf: inout [UInt8]) {
        let len = Int32(value.count)
        writeInt(&buf, len)
        for item in value {
            FfiConverterTypeEnrollmentChangeEvent.write(item, into: &buf)
        }
    }

    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [EnrollmentChangeEvent] {
        let len: Int32 = try readInt(&buf)
        var seq = [EnrollmentChangeEvent]()
        seq.reserveCapacity(Int(len))
        for _ in 0 ..< len {
            seq.append(try FfiConverterTypeEnrollmentChangeEvent.read(from: &buf))
        }
        return seq
    }
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
fileprivate struct FfiConverterSequenceTypeEnrollmentStatusExtraDef: FfiConverterRustBuffer {
    typealias SwiftType = [EnrollmentStatusExtraDef]

    public static func write(_ value: [EnrollmentStatusExtraDef], into buf: inout [UInt8]) {
        let len = Int32(value.count)
        writeInt(&buf, len)
        for item in value {
            FfiConverterTypeEnrollmentStatusExtraDef.write(item, into: &buf)
        }
    }

    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [EnrollmentStatusExtraDef] {
        let len: Int32 = try readInt(&buf)
        var seq = [EnrollmentStatusExtraDef]()
        seq.reserveCapacity(Int(len))
        for _ in 0 ..< len {
            seq.append(try FfiConverterTypeEnrollmentStatusExtraDef.read(from: &buf))
        }
        return seq
    }
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
fileprivate struct FfiConverterSequenceTypeExperimentBranch: FfiConverterRustBuffer {
    typealias SwiftType = [ExperimentBranch]

    public static func write(_ value: [ExperimentBranch], into buf: inout [UInt8]) {
        let len = Int32(value.count)
        writeInt(&buf, len)
        for item in value {
            FfiConverterTypeExperimentBranch.write(item, into: &buf)
        }
    }

    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [ExperimentBranch] {
        let len: Int32 = try readInt(&buf)
        var seq = [ExperimentBranch]()
        seq.reserveCapacity(Int(len))
        for _ in 0 ..< len {
            seq.append(try FfiConverterTypeExperimentBranch.read(from: &buf))
        }
        return seq
    }
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
fileprivate struct FfiConverterSequenceTypeGeckoPrefState: FfiConverterRustBuffer {
    typealias SwiftType = [GeckoPrefState]

    public static func write(_ value: [GeckoPrefState], into buf: inout [UInt8]) {
        let len = Int32(value.count)
        writeInt(&buf, len)
        for item in value {
            FfiConverterTypeGeckoPrefState.write(item, into: &buf)
        }
    }

    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [GeckoPrefState] {
        let len: Int32 = try readInt(&buf)
        var seq = [GeckoPrefState]()
        seq.reserveCapacity(Int(len))
        for _ in 0 ..< len {
            seq.append(try FfiConverterTypeGeckoPrefState.read(from: &buf))
        }
        return seq
    }
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
fileprivate struct FfiConverterDictionaryStringDouble: FfiConverterRustBuffer {
    public static func write(_ value: [String: Double], into buf: inout [UInt8]) {
        let len = Int32(value.count)
        writeInt(&buf, len)
        for (key, value) in value {
            FfiConverterString.write(key, into: &buf)
            FfiConverterDouble.write(value, into: &buf)
        }
    }

    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [String: Double] {
        let len: Int32 = try readInt(&buf)
        var dict = [String: Double]()
        dict.reserveCapacity(Int(len))
        for _ in 0..<len {
            let key = try FfiConverterString.read(from: &buf)
            let value = try FfiConverterDouble.read(from: &buf)
            dict[key] = value
        }
        return dict
    }
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
fileprivate struct FfiConverterDictionaryStringString: FfiConverterRustBuffer {
    public static func write(_ value: [String: String], into buf: inout [UInt8]) {
        let len = Int32(value.count)
        writeInt(&buf, len)
        for (key, value) in value {
            FfiConverterString.write(key, into: &buf)
            FfiConverterString.write(value, into: &buf)
        }
    }

    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [String: String] {
        let len: Int32 = try readInt(&buf)
        var dict = [String: String]()
        dict.reserveCapacity(Int(len))
        for _ in 0..<len {
            let key = try FfiConverterString.read(from: &buf)
            let value = try FfiConverterString.read(from: &buf)
            dict[key] = value
        }
        return dict
    }
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
fileprivate struct FfiConverterDictionaryStringTypeGeckoPrefState: FfiConverterRustBuffer {
    public static func write(_ value: [String: GeckoPrefState], into buf: inout [UInt8]) {
        let len = Int32(value.count)
        writeInt(&buf, len)
        for (key, value) in value {
            FfiConverterString.write(key, into: &buf)
            FfiConverterTypeGeckoPrefState.write(value, into: &buf)
        }
    }

    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [String: GeckoPrefState] {
        let len: Int32 = try readInt(&buf)
        var dict = [String: GeckoPrefState]()
        dict.reserveCapacity(Int(len))
        for _ in 0..<len {
            let key = try FfiConverterString.read(from: &buf)
            let value = try FfiConverterTypeGeckoPrefState.read(from: &buf)
            dict[key] = value
        }
        return dict
    }
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
fileprivate struct FfiConverterDictionaryStringDictionaryStringTypeGeckoPrefState: FfiConverterRustBuffer {
    public static func write(_ value: [String: [String: GeckoPrefState]], into buf: inout [UInt8]) {
        let len = Int32(value.count)
        writeInt(&buf, len)
        for (key, value) in value {
            FfiConverterString.write(key, into: &buf)
            FfiConverterDictionaryStringTypeGeckoPrefState.write(value, into: &buf)
        }
    }

    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [String: [String: GeckoPrefState]] {
        let len: Int32 = try readInt(&buf)
        var dict = [String: [String: GeckoPrefState]]()
        dict.reserveCapacity(Int(len))
        for _ in 0..<len {
            let key = try FfiConverterString.read(from: &buf)
            let value = try FfiConverterDictionaryStringTypeGeckoPrefState.read(from: &buf)
            dict[key] = value
        }
        return dict
    }
}


/**
 * Typealias from the type name used in the UDL file to the builtin type.  This
 * is needed because the UDL type name is used in function/method signatures.
 */
public typealias JsonObject = String

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public struct FfiConverterTypeJsonObject: FfiConverter {
    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> JsonObject {
        return try FfiConverterString.read(from: &buf)
    }

    public static func write(_ value: JsonObject, into buf: inout [UInt8]) {
        return FfiConverterString.write(value, into: &buf)
    }

    public static func lift(_ value: RustBuffer) throws -> JsonObject {
        return try FfiConverterString.lift(value)
    }

    public static func lower(_ value: JsonObject) -> RustBuffer {
        return FfiConverterString.lower(value)
    }
}


#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeJsonObject_lift(_ value: RustBuffer) throws -> JsonObject {
    return try FfiConverterTypeJsonObject.lift(value)
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeJsonObject_lower(_ value: JsonObject) -> RustBuffer {
    return FfiConverterTypeJsonObject.lower(value)
}



/**
 * Typealias from the type name used in the UDL file to the builtin type.  This
 * is needed because the UDL type name is used in function/method signatures.
 */
public typealias PrefValue = String

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public struct FfiConverterTypePrefValue: FfiConverter {
    public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PrefValue {
        return try FfiConverterString.read(from: &buf)
    }

    public static func write(_ value: PrefValue, into buf: inout [UInt8]) {
        return FfiConverterString.write(value, into: &buf)
    }

    public static func lift(_ value: RustBuffer) throws -> PrefValue {
        return try FfiConverterString.lift(value)
    }

    public static func lower(_ value: PrefValue) -> RustBuffer {
        return FfiConverterString.lower(value)
    }
}


#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypePrefValue_lift(_ value: RustBuffer) throws -> PrefValue {
    return try FfiConverterTypePrefValue.lift(value)
}

#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypePrefValue_lower(_ value: PrefValue) -> RustBuffer {
    return FfiConverterTypePrefValue.lower(value)
}

/**

 */
public func getCalculatedAttributes(installationDate: Int64?, dbPath: String, locale: String)throws  -> CalculatedAttributes  {
    return try  FfiConverterTypeCalculatedAttributes_lift(try rustCallWithError(FfiConverterTypeNimbusError_lift) {
    uniffi_nimbus_fn_func_get_calculated_attributes(
        FfiConverterOptionInt64.lower(installationDate),
        FfiConverterString.lower(dbPath),
        FfiConverterString.lower(locale),$0
    )
})
}
/**
 * A test utility used to validate event queries against the jexl evaluator.
 *
 * This method should only be used in tests.
 */
public func validateEventQueries(recordedContext: RecordedContext)throws   {try rustCallWithError(FfiConverterTypeNimbusError_lift) {
    uniffi_nimbus_fn_func_validate_event_queries(
        FfiConverterTypeRecordedContext_lower(recordedContext),$0
    )
}
}

private enum InitializationResult {
    case ok
    case contractVersionMismatch
    case apiChecksumMismatch
}
// Use a global variable to perform the versioning checks. Swift ensures that
// the code inside is only computed once.
private let initializationResult: InitializationResult = {
    // Get the bindings contract version from our ComponentInterface
    let bindings_contract_version = 29
    // Get the scaffolding contract version by calling the into the dylib
    let scaffolding_contract_version = ffi_nimbus_uniffi_contract_version()
    if bindings_contract_version != scaffolding_contract_version {
        return InitializationResult.contractVersionMismatch
    }
    if (uniffi_nimbus_checksum_func_get_calculated_attributes() != 10534) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_func_validate_event_queries() != 42746) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_nimbusclient_advance_event_time() != 40755) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_nimbusclient_apply_pending_experiments() != 21020) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_nimbusclient_clear_events() != 38691) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_nimbusclient_create_string_helper() != 48136) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_nimbusclient_create_targeting_helper() != 37928) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_nimbusclient_dump_state_to_log() != 43374) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_nimbusclient_fetch_experiments() != 7325) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_nimbusclient_get_active_experiments() != 63303) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_nimbusclient_get_available_experiments() != 53590) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_nimbusclient_get_experiment_branch() != 35089) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_nimbusclient_get_experiment_branches() != 60563) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_nimbusclient_get_feature_config_variables() != 7354) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_nimbusclient_get_global_user_participation() != 53001) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_nimbusclient_initialize() != 500) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_nimbusclient_is_fetch_enabled() != 9890) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_nimbusclient_opt_in_with_branch() != 54676) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_nimbusclient_opt_out() != 19195) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_nimbusclient_record_event() != 60856) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_nimbusclient_record_feature_exposure() != 19276) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_nimbusclient_record_malformed_feature_config() != 52482) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_nimbusclient_record_past_event() != 4442) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_nimbusclient_reset_enrollments() != 39284) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_nimbusclient_reset_telemetry_identifiers() != 44528) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_nimbusclient_set_experiments_locally() != 29563) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_nimbusclient_set_fetch_enabled() != 64996) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_nimbusclient_set_global_user_participation() != 42180) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_nimbusclient_unenroll_for_gecko_pref() != 40841) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_nimbusstringhelper_get_uuid() != 24293) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_nimbusstringhelper_string_format() != 12685) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_nimbustargetinghelper_eval_jexl() != 42395) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_recordedcontext_get_event_queries() != 28844) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_recordedcontext_record() != 5916) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_recordedcontext_set_event_query_values() != 40199) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_recordedcontext_to_json() != 46595) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_constructor_nimbusclient_new() != 16871) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_geckoprefhandler_get_prefs_with_state() != 54971) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_geckoprefhandler_set_gecko_prefs_state() != 51120) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_metricshandler_record_enrollment_statuses() != 22229) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_metricshandler_record_feature_activation() != 6186) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_metricshandler_record_feature_exposure() != 14029) {
        return InitializationResult.apiChecksumMismatch
    }
    if (uniffi_nimbus_checksum_method_metricshandler_record_malformed_feature_config() != 29240) {
        return InitializationResult.apiChecksumMismatch
    }

    uniffiCallbackInitRecordedContext()
    uniffiCallbackInitGeckoPrefHandler()
    uniffiCallbackInitMetricsHandler()
    uniffiEnsureRemoteSettingsInitialized()
    return InitializationResult.ok
}()

// Make the ensure init function public so that other modules which have external type references to
// our types can call it.
public func uniffiEnsureNimbusInitialized() {
    switch initializationResult {
    case .ok:
        break
    case .contractVersionMismatch:
        fatalError("UniFFI contract version mismatch: try cleaning and rebuilding your project")
    case .apiChecksumMismatch:
        fatalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
    }
}

// swiftlint:enable all