swift-source/all/Generated/remote_settings.swift (1,596 lines of code) (raw):

// 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_remote_settings_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_remote_settings_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 { uniffiEnsureRemoteSettingsInitialized() 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 FfiConverterUInt64: FfiConverterPrimitive { typealias FfiType = UInt64 typealias SwiftType = UInt64 public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> UInt64 { return try lift(readInt(&buf)) } public static func write(_ value: SwiftType, into buf: inout [UInt8]) { writeInt(&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) } } #if swift(>=5.8) @_documentation(visibility: private) #endif fileprivate struct FfiConverterData: FfiConverterRustBuffer { typealias SwiftType = Data public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Data { let len: Int32 = try readInt(&buf) return Data(try readBytes(&buf, count: Int(len))) } public static func write(_ value: Data, into buf: inout [UInt8]) { let len = Int32(value.count) writeInt(&buf, len) writeBytes(&buf, value) } } public protocol RemoteSettingsProtocol: AnyObject { /** * Download an attachment with the provided id to the provided path. */ func downloadAttachmentToPath(attachmentId: String, path: String) throws /** * Fetch all records for the configuration this client was initialized with. */ func getRecords() throws -> RemoteSettingsResponse /** * Fetch all records added to the server since the provided timestamp, * using the configuration this client was initialized with. */ func getRecordsSince(timestamp: UInt64) throws -> RemoteSettingsResponse } open class RemoteSettings: RemoteSettingsProtocol, @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_remote_settings_fn_clone_remotesettings(self.pointer, $0) } } /** * Construct a new Remote Settings client with the given configuration. */ public convenience init(remoteSettingsConfig: RemoteSettingsConfig)throws { let pointer = try rustCallWithError(FfiConverterTypeRemoteSettingsError_lift) { uniffi_remote_settings_fn_constructor_remotesettings_new( FfiConverterTypeRemoteSettingsConfig_lower(remoteSettingsConfig),$0 ) } self.init(unsafeFromRawPointer: pointer) } deinit { guard let pointer = pointer else { return } try! rustCall { uniffi_remote_settings_fn_free_remotesettings(pointer, $0) } } /** * Download an attachment with the provided id to the provided path. */ open func downloadAttachmentToPath(attachmentId: String, path: String)throws {try rustCallWithError(FfiConverterTypeRemoteSettingsError_lift) { uniffi_remote_settings_fn_method_remotesettings_download_attachment_to_path(self.uniffiClonePointer(), FfiConverterString.lower(attachmentId), FfiConverterString.lower(path),$0 ) } } /** * Fetch all records for the configuration this client was initialized with. */ open func getRecords()throws -> RemoteSettingsResponse { return try FfiConverterTypeRemoteSettingsResponse_lift(try rustCallWithError(FfiConverterTypeRemoteSettingsError_lift) { uniffi_remote_settings_fn_method_remotesettings_get_records(self.uniffiClonePointer(),$0 ) }) } /** * Fetch all records added to the server since the provided timestamp, * using the configuration this client was initialized with. */ open func getRecordsSince(timestamp: UInt64)throws -> RemoteSettingsResponse { return try FfiConverterTypeRemoteSettingsResponse_lift(try rustCallWithError(FfiConverterTypeRemoteSettingsError_lift) { uniffi_remote_settings_fn_method_remotesettings_get_records_since(self.uniffiClonePointer(), FfiConverterUInt64.lower(timestamp),$0 ) }) } } #if swift(>=5.8) @_documentation(visibility: private) #endif public struct FfiConverterTypeRemoteSettings: FfiConverter { typealias FfiType = UnsafeMutableRawPointer typealias SwiftType = RemoteSettings public static func lift(_ pointer: UnsafeMutableRawPointer) throws -> RemoteSettings { return RemoteSettings(unsafeFromRawPointer: pointer) } public static func lower(_ value: RemoteSettings) -> UnsafeMutableRawPointer { return value.uniffiClonePointer() } public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> RemoteSettings { 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: RemoteSettings, 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 FfiConverterTypeRemoteSettings_lift(_ pointer: UnsafeMutableRawPointer) throws -> RemoteSettings { return try FfiConverterTypeRemoteSettings.lift(pointer) } #if swift(>=5.8) @_documentation(visibility: private) #endif public func FfiConverterTypeRemoteSettings_lower(_ value: RemoteSettings) -> UnsafeMutableRawPointer { return FfiConverterTypeRemoteSettings.lower(value) } /** * Client for a single Remote Settings collection * * Use [RemoteSettingsService::make_client] to create these. */ public protocol RemoteSettingsClientProtocol: AnyObject { /** * Collection this client is for */ func collectionName() -> String /** * Get attachment data for a remote settings record * * Attachments are large binary blobs used for data that doesn't fit in a normal record. They * are handled differently than other record data: * * - Attachments are not downloaded in [RemoteSettingsService::sync] * - This method will make network requests if the attachment is not cached * - This method will throw if there is a network or other error when fetching the * attachment data. */ func getAttachment(record: RemoteSettingsRecord) throws -> Data /** * Get the current set of records. * * This method normally fetches records from the last sync. This means that it returns fast * and does not make any network requests. * * If records have not yet been synced it will return None. Use `sync_if_empty = true` to * change this behavior and perform a network request in this case. That this is probably a * bad idea if you want to fetch the setting in application startup or when building the UI. * * None will also be returned on disk IO errors or other unexpected errors. The reason for * this is that there is not much an application can do in this situation other than fall back * to the same default handling as if records have not been synced. * * Application-services schedules regular dumps of the server data for specific collections. * For these collections, `get_records` will never return None. If you would like to add your * collection to this list, please reach out to the DISCO team. */ func getRecords(syncIfEmpty: Bool) -> [RemoteSettingsRecord]? /** * Get the current set of records as a map of record_id -> record. * * See [Self::get_records] for an explanation of when this makes network requests, error * handling, and how the `sync_if_empty` param works. */ func getRecordsMap(syncIfEmpty: Bool) -> [String: RemoteSettingsRecord]? /** * Shutdown the client, releasing the SQLite connection used to cache records. */ func shutdown() func sync() throws } /** * Client for a single Remote Settings collection * * Use [RemoteSettingsService::make_client] to create these. */ open class RemoteSettingsClient: RemoteSettingsClientProtocol, @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_remote_settings_fn_clone_remotesettingsclient(self.pointer, $0) } } // No primary constructor declared for this class. deinit { guard let pointer = pointer else { return } try! rustCall { uniffi_remote_settings_fn_free_remotesettingsclient(pointer, $0) } } /** * Collection this client is for */ open func collectionName() -> String { return try! FfiConverterString.lift(try! rustCall() { uniffi_remote_settings_fn_method_remotesettingsclient_collection_name(self.uniffiClonePointer(),$0 ) }) } /** * Get attachment data for a remote settings record * * Attachments are large binary blobs used for data that doesn't fit in a normal record. They * are handled differently than other record data: * * - Attachments are not downloaded in [RemoteSettingsService::sync] * - This method will make network requests if the attachment is not cached * - This method will throw if there is a network or other error when fetching the * attachment data. */ open func getAttachment(record: RemoteSettingsRecord)throws -> Data { return try FfiConverterData.lift(try rustCallWithError(FfiConverterTypeRemoteSettingsError_lift) { uniffi_remote_settings_fn_method_remotesettingsclient_get_attachment(self.uniffiClonePointer(), FfiConverterTypeRemoteSettingsRecord_lower(record),$0 ) }) } /** * Get the current set of records. * * This method normally fetches records from the last sync. This means that it returns fast * and does not make any network requests. * * If records have not yet been synced it will return None. Use `sync_if_empty = true` to * change this behavior and perform a network request in this case. That this is probably a * bad idea if you want to fetch the setting in application startup or when building the UI. * * None will also be returned on disk IO errors or other unexpected errors. The reason for * this is that there is not much an application can do in this situation other than fall back * to the same default handling as if records have not been synced. * * Application-services schedules regular dumps of the server data for specific collections. * For these collections, `get_records` will never return None. If you would like to add your * collection to this list, please reach out to the DISCO team. */ open func getRecords(syncIfEmpty: Bool = false) -> [RemoteSettingsRecord]? { return try! FfiConverterOptionSequenceTypeRemoteSettingsRecord.lift(try! rustCall() { uniffi_remote_settings_fn_method_remotesettingsclient_get_records(self.uniffiClonePointer(), FfiConverterBool.lower(syncIfEmpty),$0 ) }) } /** * Get the current set of records as a map of record_id -> record. * * See [Self::get_records] for an explanation of when this makes network requests, error * handling, and how the `sync_if_empty` param works. */ open func getRecordsMap(syncIfEmpty: Bool = false) -> [String: RemoteSettingsRecord]? { return try! FfiConverterOptionDictionaryStringTypeRemoteSettingsRecord.lift(try! rustCall() { uniffi_remote_settings_fn_method_remotesettingsclient_get_records_map(self.uniffiClonePointer(), FfiConverterBool.lower(syncIfEmpty),$0 ) }) } /** * Shutdown the client, releasing the SQLite connection used to cache records. */ open func shutdown() {try! rustCall() { uniffi_remote_settings_fn_method_remotesettingsclient_shutdown(self.uniffiClonePointer(),$0 ) } } open func sync()throws {try rustCallWithError(FfiConverterTypeRemoteSettingsError_lift) { uniffi_remote_settings_fn_method_remotesettingsclient_sync(self.uniffiClonePointer(),$0 ) } } } #if swift(>=5.8) @_documentation(visibility: private) #endif public struct FfiConverterTypeRemoteSettingsClient: FfiConverter { typealias FfiType = UnsafeMutableRawPointer typealias SwiftType = RemoteSettingsClient public static func lift(_ pointer: UnsafeMutableRawPointer) throws -> RemoteSettingsClient { return RemoteSettingsClient(unsafeFromRawPointer: pointer) } public static func lower(_ value: RemoteSettingsClient) -> UnsafeMutableRawPointer { return value.uniffiClonePointer() } public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> RemoteSettingsClient { 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: RemoteSettingsClient, 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 FfiConverterTypeRemoteSettingsClient_lift(_ pointer: UnsafeMutableRawPointer) throws -> RemoteSettingsClient { return try FfiConverterTypeRemoteSettingsClient.lift(pointer) } #if swift(>=5.8) @_documentation(visibility: private) #endif public func FfiConverterTypeRemoteSettingsClient_lower(_ value: RemoteSettingsClient) -> UnsafeMutableRawPointer { return FfiConverterTypeRemoteSettingsClient.lower(value) } /** * Application-level Remote Settings manager. * * This handles application-level operations, like syncing all the collections, and acts as a * factory for creating clients. */ public protocol RemoteSettingsServiceProtocol: AnyObject { /** * Create a new Remote Settings client * * This method performs no IO or network requests and is safe to run in a main thread that can't be blocked. */ func makeClient(collectionName: String) -> RemoteSettingsClient /** * Sync collections for all active clients */ func sync() throws -> [String] /** * Update the remote settings config * * This will cause all current and future clients to use new config and will delete any stored * records causing the clients to return new results from the new config. * * Only intended for QA/debugging. Swapping the remote settings server in the middle of * execution can cause weird effects. */ func updateConfig(config: RemoteSettingsConfig2) throws } /** * Application-level Remote Settings manager. * * This handles application-level operations, like syncing all the collections, and acts as a * factory for creating clients. */ open class RemoteSettingsService: RemoteSettingsServiceProtocol, @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_remote_settings_fn_clone_remotesettingsservice(self.pointer, $0) } } /** * Construct a [RemoteSettingsService] * * This is typically done early in the application-startup process. * * This method performs no IO or network requests and is safe to run in a main thread that * can't be blocked. * * `storage_dir` is a directory to store SQLite files in -- one per collection. If the * directory does not exist, it will be created when the storage is first used. Only the * directory and the SQLite files will be created, any parent directories must already exist. */ public convenience init(storageDir: String, config: RemoteSettingsConfig2) { let pointer = try! rustCall() { uniffi_remote_settings_fn_constructor_remotesettingsservice_new( FfiConverterString.lower(storageDir), FfiConverterTypeRemoteSettingsConfig2_lower(config),$0 ) } self.init(unsafeFromRawPointer: pointer) } deinit { guard let pointer = pointer else { return } try! rustCall { uniffi_remote_settings_fn_free_remotesettingsservice(pointer, $0) } } /** * Create a new Remote Settings client * * This method performs no IO or network requests and is safe to run in a main thread that can't be blocked. */ open func makeClient(collectionName: String) -> RemoteSettingsClient { return try! FfiConverterTypeRemoteSettingsClient_lift(try! rustCall() { uniffi_remote_settings_fn_method_remotesettingsservice_make_client(self.uniffiClonePointer(), FfiConverterString.lower(collectionName),$0 ) }) } /** * Sync collections for all active clients */ open func sync()throws -> [String] { return try FfiConverterSequenceString.lift(try rustCallWithError(FfiConverterTypeRemoteSettingsError_lift) { uniffi_remote_settings_fn_method_remotesettingsservice_sync(self.uniffiClonePointer(),$0 ) }) } /** * Update the remote settings config * * This will cause all current and future clients to use new config and will delete any stored * records causing the clients to return new results from the new config. * * Only intended for QA/debugging. Swapping the remote settings server in the middle of * execution can cause weird effects. */ open func updateConfig(config: RemoteSettingsConfig2)throws {try rustCallWithError(FfiConverterTypeRemoteSettingsError_lift) { uniffi_remote_settings_fn_method_remotesettingsservice_update_config(self.uniffiClonePointer(), FfiConverterTypeRemoteSettingsConfig2_lower(config),$0 ) } } } #if swift(>=5.8) @_documentation(visibility: private) #endif public struct FfiConverterTypeRemoteSettingsService: FfiConverter { typealias FfiType = UnsafeMutableRawPointer typealias SwiftType = RemoteSettingsService public static func lift(_ pointer: UnsafeMutableRawPointer) throws -> RemoteSettingsService { return RemoteSettingsService(unsafeFromRawPointer: pointer) } public static func lower(_ value: RemoteSettingsService) -> UnsafeMutableRawPointer { return value.uniffiClonePointer() } public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> RemoteSettingsService { 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: RemoteSettingsService, 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 FfiConverterTypeRemoteSettingsService_lift(_ pointer: UnsafeMutableRawPointer) throws -> RemoteSettingsService { return try FfiConverterTypeRemoteSettingsService.lift(pointer) } #if swift(>=5.8) @_documentation(visibility: private) #endif public func FfiConverterTypeRemoteSettingsService_lower(_ value: RemoteSettingsService) -> UnsafeMutableRawPointer { return FfiConverterTypeRemoteSettingsService.lower(value) } /** * Attachment metadata that can be optionally attached to a [Record]. The [location] should * included in calls to [Client::get_attachment]. */ public struct Attachment { public var filename: String public var mimetype: String public var location: String public var hash: String public var size: UInt64 // Default memberwise initializers are never public by default, so we // declare one manually. public init(filename: String, mimetype: String, location: String, hash: String, size: UInt64) { self.filename = filename self.mimetype = mimetype self.location = location self.hash = hash self.size = size } } #if compiler(>=6) extension Attachment: Sendable {} #endif extension Attachment: Equatable, Hashable { public static func ==(lhs: Attachment, rhs: Attachment) -> Bool { if lhs.filename != rhs.filename { return false } if lhs.mimetype != rhs.mimetype { return false } if lhs.location != rhs.location { return false } if lhs.hash != rhs.hash { return false } if lhs.size != rhs.size { return false } return true } public func hash(into hasher: inout Hasher) { hasher.combine(filename) hasher.combine(mimetype) hasher.combine(location) hasher.combine(hash) hasher.combine(size) } } #if swift(>=5.8) @_documentation(visibility: private) #endif public struct FfiConverterTypeAttachment: FfiConverterRustBuffer { public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Attachment { return try Attachment( filename: FfiConverterString.read(from: &buf), mimetype: FfiConverterString.read(from: &buf), location: FfiConverterString.read(from: &buf), hash: FfiConverterString.read(from: &buf), size: FfiConverterUInt64.read(from: &buf) ) } public static func write(_ value: Attachment, into buf: inout [UInt8]) { FfiConverterString.write(value.filename, into: &buf) FfiConverterString.write(value.mimetype, into: &buf) FfiConverterString.write(value.location, into: &buf) FfiConverterString.write(value.hash, into: &buf) FfiConverterUInt64.write(value.size, into: &buf) } } #if swift(>=5.8) @_documentation(visibility: private) #endif public func FfiConverterTypeAttachment_lift(_ buf: RustBuffer) throws -> Attachment { return try FfiConverterTypeAttachment.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif public func FfiConverterTypeAttachment_lower(_ value: Attachment) -> RustBuffer { return FfiConverterTypeAttachment.lower(value) } /** * Custom configuration for the client. * Currently includes the following: * - `server`: The Remote Settings server to use. If not specified, defaults to the production server (`RemoteSettingsServer::Prod`). * - `server_url`: An optional custom Remote Settings server URL. Deprecated; please use `server` instead. * - `bucket_name`: The optional name of the bucket containing the collection on the server. If not specified, the standard bucket will be used. * - `collection_name`: The name of the collection for the settings server. */ public struct RemoteSettingsConfig { public var collectionName: String public var bucketName: String? public var serverUrl: String? public var server: RemoteSettingsServer? // Default memberwise initializers are never public by default, so we // declare one manually. public init(collectionName: String, bucketName: String? = nil, serverUrl: String? = nil, server: RemoteSettingsServer? = nil) { self.collectionName = collectionName self.bucketName = bucketName self.serverUrl = serverUrl self.server = server } } #if compiler(>=6) extension RemoteSettingsConfig: Sendable {} #endif extension RemoteSettingsConfig: Equatable, Hashable { public static func ==(lhs: RemoteSettingsConfig, rhs: RemoteSettingsConfig) -> Bool { if lhs.collectionName != rhs.collectionName { return false } if lhs.bucketName != rhs.bucketName { return false } if lhs.serverUrl != rhs.serverUrl { return false } if lhs.server != rhs.server { return false } return true } public func hash(into hasher: inout Hasher) { hasher.combine(collectionName) hasher.combine(bucketName) hasher.combine(serverUrl) hasher.combine(server) } } #if swift(>=5.8) @_documentation(visibility: private) #endif public struct FfiConverterTypeRemoteSettingsConfig: FfiConverterRustBuffer { public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> RemoteSettingsConfig { return try RemoteSettingsConfig( collectionName: FfiConverterString.read(from: &buf), bucketName: FfiConverterOptionString.read(from: &buf), serverUrl: FfiConverterOptionString.read(from: &buf), server: FfiConverterOptionTypeRemoteSettingsServer.read(from: &buf) ) } public static func write(_ value: RemoteSettingsConfig, into buf: inout [UInt8]) { FfiConverterString.write(value.collectionName, into: &buf) FfiConverterOptionString.write(value.bucketName, into: &buf) FfiConverterOptionString.write(value.serverUrl, into: &buf) FfiConverterOptionTypeRemoteSettingsServer.write(value.server, into: &buf) } } #if swift(>=5.8) @_documentation(visibility: private) #endif public func FfiConverterTypeRemoteSettingsConfig_lift(_ buf: RustBuffer) throws -> RemoteSettingsConfig { return try FfiConverterTypeRemoteSettingsConfig.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif public func FfiConverterTypeRemoteSettingsConfig_lower(_ value: RemoteSettingsConfig) -> RustBuffer { return FfiConverterTypeRemoteSettingsConfig.lower(value) } /** * Remote settings configuration * * This is the version used in the new API, hence the `2` at the end. The plan is to move * consumers to the new API, remove the RemoteSettingsConfig struct, then remove the `2` from this * name. */ public struct RemoteSettingsConfig2 { /** * The Remote Settings server to use. Defaults to [RemoteSettingsServer::Prod], */ public var server: RemoteSettingsServer? /** * Bucket name to use, defaults to "main". Use "main-preview" for a preview bucket */ public var bucketName: String? /** * App context to use for JEXL filtering (when the `jexl` feature is present). */ public var appContext: RemoteSettingsContext? // Default memberwise initializers are never public by default, so we // declare one manually. public init( /** * The Remote Settings server to use. Defaults to [RemoteSettingsServer::Prod], */server: RemoteSettingsServer? = nil, /** * Bucket name to use, defaults to "main". Use "main-preview" for a preview bucket */bucketName: String? = nil, /** * App context to use for JEXL filtering (when the `jexl` feature is present). */appContext: RemoteSettingsContext? = nil) { self.server = server self.bucketName = bucketName self.appContext = appContext } } #if compiler(>=6) extension RemoteSettingsConfig2: Sendable {} #endif extension RemoteSettingsConfig2: Equatable, Hashable { public static func ==(lhs: RemoteSettingsConfig2, rhs: RemoteSettingsConfig2) -> Bool { if lhs.server != rhs.server { return false } if lhs.bucketName != rhs.bucketName { return false } if lhs.appContext != rhs.appContext { return false } return true } public func hash(into hasher: inout Hasher) { hasher.combine(server) hasher.combine(bucketName) hasher.combine(appContext) } } #if swift(>=5.8) @_documentation(visibility: private) #endif public struct FfiConverterTypeRemoteSettingsConfig2: FfiConverterRustBuffer { public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> RemoteSettingsConfig2 { return try RemoteSettingsConfig2( server: FfiConverterOptionTypeRemoteSettingsServer.read(from: &buf), bucketName: FfiConverterOptionString.read(from: &buf), appContext: FfiConverterOptionTypeRemoteSettingsContext.read(from: &buf) ) } public static func write(_ value: RemoteSettingsConfig2, into buf: inout [UInt8]) { FfiConverterOptionTypeRemoteSettingsServer.write(value.server, into: &buf) FfiConverterOptionString.write(value.bucketName, into: &buf) FfiConverterOptionTypeRemoteSettingsContext.write(value.appContext, into: &buf) } } #if swift(>=5.8) @_documentation(visibility: private) #endif public func FfiConverterTypeRemoteSettingsConfig2_lift(_ buf: RustBuffer) throws -> RemoteSettingsConfig2 { return try FfiConverterTypeRemoteSettingsConfig2.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif public func FfiConverterTypeRemoteSettingsConfig2_lower(_ value: RemoteSettingsConfig2) -> RustBuffer { return FfiConverterTypeRemoteSettingsConfig2.lower(value) } /** * Remote settings context object * * This is used to filter the records returned. We always fetch all `records` from the * remote-settings storage. Some records could have a `filter_expression`. If this is passed in * and the record has a `filter_expression`, then only returns where the expression is true will * be returned. * * See https://remote-settings.readthedocs.io/en/latest/target-filters.html for details. */ public struct RemoteSettingsContext { /** * The delivery channel of the application (e.g "nightly") */ public var channel: String? /** * User visible version string (e.g. "1.0.3") */ public var appVersion: String? /** * String containing the XUL application app_id */ public var appId: String? /** * The locale of the application during initialization (e.g. "es-ES") */ public var locale: String? /** * The name of the operating system (e.g. "Android", "iOS", "Darwin", "WINNT") */ public var os: String? /** * The user-visible version of the operating system (e.g. "1.2.3") */ public var osVersion: String? /** * Form-factor of the device ("phone", "tablet", or "desktop") */ public var formFactor: String? /** * Country of the user. * * This is usually populated in one of two ways: * - The second component of the locale * - By using a geolocation service, which determines country via the user's IP. * Firefox apps usually have a module that integrates with these services, * for example `Region` on Desktop and `RegionMiddleware` on Android. */ public var country: String? /** * Extra attributes to add to the env for JEXL filtering. * * Use this for prototyping / testing new features. In the long-term, new fields should be * added to the official list and supported by both the Rust and Gecko clients. */ public var customTargettingAttributes: [String: String]? // Default memberwise initializers are never public by default, so we // declare one manually. public init( /** * The delivery channel of the application (e.g "nightly") */channel: String? = nil, /** * User visible version string (e.g. "1.0.3") */appVersion: String? = nil, /** * String containing the XUL application app_id */appId: String? = nil, /** * The locale of the application during initialization (e.g. "es-ES") */locale: String? = nil, /** * The name of the operating system (e.g. "Android", "iOS", "Darwin", "WINNT") */os: String? = nil, /** * The user-visible version of the operating system (e.g. "1.2.3") */osVersion: String? = nil, /** * Form-factor of the device ("phone", "tablet", or "desktop") */formFactor: String? = nil, /** * Country of the user. * * This is usually populated in one of two ways: * - The second component of the locale * - By using a geolocation service, which determines country via the user's IP. * Firefox apps usually have a module that integrates with these services, * for example `Region` on Desktop and `RegionMiddleware` on Android. */country: String? = nil, /** * Extra attributes to add to the env for JEXL filtering. * * Use this for prototyping / testing new features. In the long-term, new fields should be * added to the official list and supported by both the Rust and Gecko clients. */customTargettingAttributes: [String: String]? = nil) { self.channel = channel self.appVersion = appVersion self.appId = appId self.locale = locale self.os = os self.osVersion = osVersion self.formFactor = formFactor self.country = country self.customTargettingAttributes = customTargettingAttributes } } #if compiler(>=6) extension RemoteSettingsContext: Sendable {} #endif extension RemoteSettingsContext: Equatable, Hashable { public static func ==(lhs: RemoteSettingsContext, rhs: RemoteSettingsContext) -> Bool { if lhs.channel != rhs.channel { return false } if lhs.appVersion != rhs.appVersion { return false } if lhs.appId != rhs.appId { 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.formFactor != rhs.formFactor { return false } if lhs.country != rhs.country { return false } if lhs.customTargettingAttributes != rhs.customTargettingAttributes { return false } return true } public func hash(into hasher: inout Hasher) { hasher.combine(channel) hasher.combine(appVersion) hasher.combine(appId) hasher.combine(locale) hasher.combine(os) hasher.combine(osVersion) hasher.combine(formFactor) hasher.combine(country) hasher.combine(customTargettingAttributes) } } #if swift(>=5.8) @_documentation(visibility: private) #endif public struct FfiConverterTypeRemoteSettingsContext: FfiConverterRustBuffer { public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> RemoteSettingsContext { return try RemoteSettingsContext( channel: FfiConverterOptionString.read(from: &buf), appVersion: FfiConverterOptionString.read(from: &buf), appId: FfiConverterOptionString.read(from: &buf), locale: FfiConverterOptionString.read(from: &buf), os: FfiConverterOptionString.read(from: &buf), osVersion: FfiConverterOptionString.read(from: &buf), formFactor: FfiConverterOptionString.read(from: &buf), country: FfiConverterOptionString.read(from: &buf), customTargettingAttributes: FfiConverterOptionDictionaryStringString.read(from: &buf) ) } public static func write(_ value: RemoteSettingsContext, into buf: inout [UInt8]) { FfiConverterOptionString.write(value.channel, into: &buf) FfiConverterOptionString.write(value.appVersion, into: &buf) FfiConverterOptionString.write(value.appId, into: &buf) FfiConverterOptionString.write(value.locale, into: &buf) FfiConverterOptionString.write(value.os, into: &buf) FfiConverterOptionString.write(value.osVersion, into: &buf) FfiConverterOptionString.write(value.formFactor, into: &buf) FfiConverterOptionString.write(value.country, into: &buf) FfiConverterOptionDictionaryStringString.write(value.customTargettingAttributes, into: &buf) } } #if swift(>=5.8) @_documentation(visibility: private) #endif public func FfiConverterTypeRemoteSettingsContext_lift(_ buf: RustBuffer) throws -> RemoteSettingsContext { return try FfiConverterTypeRemoteSettingsContext.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif public func FfiConverterTypeRemoteSettingsContext_lower(_ value: RemoteSettingsContext) -> RustBuffer { return FfiConverterTypeRemoteSettingsContext.lower(value) } /** * A parsed Remote Settings record. Records can contain arbitrary fields, so clients * are required to further extract expected values from the [fields] member. */ public struct RemoteSettingsRecord { public var id: String public var lastModified: UInt64 /** * Tombstone flag (see https://remote-settings.readthedocs.io/en/latest/client-specifications.html#local-state) */ public var deleted: Bool public var attachment: Attachment? public var fields: RsJsonObject // Default memberwise initializers are never public by default, so we // declare one manually. public init(id: String, lastModified: UInt64, /** * Tombstone flag (see https://remote-settings.readthedocs.io/en/latest/client-specifications.html#local-state) */deleted: Bool, attachment: Attachment?, fields: RsJsonObject) { self.id = id self.lastModified = lastModified self.deleted = deleted self.attachment = attachment self.fields = fields } } #if compiler(>=6) extension RemoteSettingsRecord: Sendable {} #endif extension RemoteSettingsRecord: Equatable, Hashable { public static func ==(lhs: RemoteSettingsRecord, rhs: RemoteSettingsRecord) -> Bool { if lhs.id != rhs.id { return false } if lhs.lastModified != rhs.lastModified { return false } if lhs.deleted != rhs.deleted { return false } if lhs.attachment != rhs.attachment { return false } if lhs.fields != rhs.fields { return false } return true } public func hash(into hasher: inout Hasher) { hasher.combine(id) hasher.combine(lastModified) hasher.combine(deleted) hasher.combine(attachment) hasher.combine(fields) } } #if swift(>=5.8) @_documentation(visibility: private) #endif public struct FfiConverterTypeRemoteSettingsRecord: FfiConverterRustBuffer { public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> RemoteSettingsRecord { return try RemoteSettingsRecord( id: FfiConverterString.read(from: &buf), lastModified: FfiConverterUInt64.read(from: &buf), deleted: FfiConverterBool.read(from: &buf), attachment: FfiConverterOptionTypeAttachment.read(from: &buf), fields: FfiConverterTypeRsJsonObject.read(from: &buf) ) } public static func write(_ value: RemoteSettingsRecord, into buf: inout [UInt8]) { FfiConverterString.write(value.id, into: &buf) FfiConverterUInt64.write(value.lastModified, into: &buf) FfiConverterBool.write(value.deleted, into: &buf) FfiConverterOptionTypeAttachment.write(value.attachment, into: &buf) FfiConverterTypeRsJsonObject.write(value.fields, into: &buf) } } #if swift(>=5.8) @_documentation(visibility: private) #endif public func FfiConverterTypeRemoteSettingsRecord_lift(_ buf: RustBuffer) throws -> RemoteSettingsRecord { return try FfiConverterTypeRemoteSettingsRecord.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif public func FfiConverterTypeRemoteSettingsRecord_lower(_ value: RemoteSettingsRecord) -> RustBuffer { return FfiConverterTypeRemoteSettingsRecord.lower(value) } /** * Data structure representing the top-level response from the Remote Settings. * [last_modified] will be extracted from the etag header of the response. */ public struct RemoteSettingsResponse { public var records: [RemoteSettingsRecord] public var lastModified: UInt64 // Default memberwise initializers are never public by default, so we // declare one manually. public init(records: [RemoteSettingsRecord], lastModified: UInt64) { self.records = records self.lastModified = lastModified } } #if compiler(>=6) extension RemoteSettingsResponse: Sendable {} #endif extension RemoteSettingsResponse: Equatable, Hashable { public static func ==(lhs: RemoteSettingsResponse, rhs: RemoteSettingsResponse) -> Bool { if lhs.records != rhs.records { return false } if lhs.lastModified != rhs.lastModified { return false } return true } public func hash(into hasher: inout Hasher) { hasher.combine(records) hasher.combine(lastModified) } } #if swift(>=5.8) @_documentation(visibility: private) #endif public struct FfiConverterTypeRemoteSettingsResponse: FfiConverterRustBuffer { public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> RemoteSettingsResponse { return try RemoteSettingsResponse( records: FfiConverterSequenceTypeRemoteSettingsRecord.read(from: &buf), lastModified: FfiConverterUInt64.read(from: &buf) ) } public static func write(_ value: RemoteSettingsResponse, into buf: inout [UInt8]) { FfiConverterSequenceTypeRemoteSettingsRecord.write(value.records, into: &buf) FfiConverterUInt64.write(value.lastModified, into: &buf) } } #if swift(>=5.8) @_documentation(visibility: private) #endif public func FfiConverterTypeRemoteSettingsResponse_lift(_ buf: RustBuffer) throws -> RemoteSettingsResponse { return try FfiConverterTypeRemoteSettingsResponse.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif public func FfiConverterTypeRemoteSettingsResponse_lower(_ value: RemoteSettingsResponse) -> RustBuffer { return FfiConverterTypeRemoteSettingsResponse.lower(value) } /** * Public error class, this is what we return to consumers */ public enum RemoteSettingsError { /** * Network error while making a remote settings request */ case Network(reason: String ) /** * The server has asked the client to backoff. */ case Backoff(seconds: UInt64 ) case Other(reason: String ) } #if swift(>=5.8) @_documentation(visibility: private) #endif public struct FfiConverterTypeRemoteSettingsError: FfiConverterRustBuffer { typealias SwiftType = RemoteSettingsError public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> RemoteSettingsError { let variant: Int32 = try readInt(&buf) switch variant { case 1: return .Network( reason: try FfiConverterString.read(from: &buf) ) case 2: return .Backoff( seconds: try FfiConverterUInt64.read(from: &buf) ) case 3: return .Other( reason: try FfiConverterString.read(from: &buf) ) default: throw UniffiInternalError.unexpectedEnumCase } } public static func write(_ value: RemoteSettingsError, into buf: inout [UInt8]) { switch value { case let .Network(reason): writeInt(&buf, Int32(1)) FfiConverterString.write(reason, into: &buf) case let .Backoff(seconds): writeInt(&buf, Int32(2)) FfiConverterUInt64.write(seconds, into: &buf) case let .Other(reason): writeInt(&buf, Int32(3)) FfiConverterString.write(reason, into: &buf) } } } #if swift(>=5.8) @_documentation(visibility: private) #endif public func FfiConverterTypeRemoteSettingsError_lift(_ buf: RustBuffer) throws -> RemoteSettingsError { return try FfiConverterTypeRemoteSettingsError.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif public func FfiConverterTypeRemoteSettingsError_lower(_ value: RemoteSettingsError) -> RustBuffer { return FfiConverterTypeRemoteSettingsError.lower(value) } extension RemoteSettingsError: Equatable, Hashable {} extension RemoteSettingsError: 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. /** * The Remote Settings server that the client should use. */ public enum RemoteSettingsServer { case prod case stage case dev case custom(url: String ) } #if compiler(>=6) extension RemoteSettingsServer: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif public struct FfiConverterTypeRemoteSettingsServer: FfiConverterRustBuffer { typealias SwiftType = RemoteSettingsServer public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> RemoteSettingsServer { let variant: Int32 = try readInt(&buf) switch variant { case 1: return .prod case 2: return .stage case 3: return .dev case 4: return .custom(url: try FfiConverterString.read(from: &buf) ) default: throw UniffiInternalError.unexpectedEnumCase } } public static func write(_ value: RemoteSettingsServer, into buf: inout [UInt8]) { switch value { case .prod: writeInt(&buf, Int32(1)) case .stage: writeInt(&buf, Int32(2)) case .dev: writeInt(&buf, Int32(3)) case let .custom(url): writeInt(&buf, Int32(4)) FfiConverterString.write(url, into: &buf) } } } #if swift(>=5.8) @_documentation(visibility: private) #endif public func FfiConverterTypeRemoteSettingsServer_lift(_ buf: RustBuffer) throws -> RemoteSettingsServer { return try FfiConverterTypeRemoteSettingsServer.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif public func FfiConverterTypeRemoteSettingsServer_lower(_ value: RemoteSettingsServer) -> RustBuffer { return FfiConverterTypeRemoteSettingsServer.lower(value) } extension RemoteSettingsServer: Equatable, Hashable {} #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 FfiConverterOptionTypeAttachment: FfiConverterRustBuffer { typealias SwiftType = Attachment? public static func write(_ value: SwiftType, into buf: inout [UInt8]) { guard let value = value else { writeInt(&buf, Int8(0)) return } writeInt(&buf, Int8(1)) FfiConverterTypeAttachment.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 FfiConverterTypeAttachment.read(from: &buf) default: throw UniffiInternalError.unexpectedOptionalTag } } } #if swift(>=5.8) @_documentation(visibility: private) #endif fileprivate struct FfiConverterOptionTypeRemoteSettingsContext: FfiConverterRustBuffer { typealias SwiftType = RemoteSettingsContext? public static func write(_ value: SwiftType, into buf: inout [UInt8]) { guard let value = value else { writeInt(&buf, Int8(0)) return } writeInt(&buf, Int8(1)) FfiConverterTypeRemoteSettingsContext.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 FfiConverterTypeRemoteSettingsContext.read(from: &buf) default: throw UniffiInternalError.unexpectedOptionalTag } } } #if swift(>=5.8) @_documentation(visibility: private) #endif fileprivate struct FfiConverterOptionTypeRemoteSettingsServer: FfiConverterRustBuffer { typealias SwiftType = RemoteSettingsServer? public static func write(_ value: SwiftType, into buf: inout [UInt8]) { guard let value = value else { writeInt(&buf, Int8(0)) return } writeInt(&buf, Int8(1)) FfiConverterTypeRemoteSettingsServer.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 FfiConverterTypeRemoteSettingsServer.read(from: &buf) default: throw UniffiInternalError.unexpectedOptionalTag } } } #if swift(>=5.8) @_documentation(visibility: private) #endif fileprivate struct FfiConverterOptionSequenceTypeRemoteSettingsRecord: FfiConverterRustBuffer { typealias SwiftType = [RemoteSettingsRecord]? public static func write(_ value: SwiftType, into buf: inout [UInt8]) { guard let value = value else { writeInt(&buf, Int8(0)) return } writeInt(&buf, Int8(1)) FfiConverterSequenceTypeRemoteSettingsRecord.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 FfiConverterSequenceTypeRemoteSettingsRecord.read(from: &buf) default: throw UniffiInternalError.unexpectedOptionalTag } } } #if swift(>=5.8) @_documentation(visibility: private) #endif fileprivate struct FfiConverterOptionDictionaryStringString: FfiConverterRustBuffer { typealias SwiftType = [String: 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)) FfiConverterDictionaryStringString.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 FfiConverterDictionaryStringString.read(from: &buf) default: throw UniffiInternalError.unexpectedOptionalTag } } } #if swift(>=5.8) @_documentation(visibility: private) #endif fileprivate struct FfiConverterOptionDictionaryStringTypeRemoteSettingsRecord: FfiConverterRustBuffer { typealias SwiftType = [String: RemoteSettingsRecord]? public static func write(_ value: SwiftType, into buf: inout [UInt8]) { guard let value = value else { writeInt(&buf, Int8(0)) return } writeInt(&buf, Int8(1)) FfiConverterDictionaryStringTypeRemoteSettingsRecord.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 FfiConverterDictionaryStringTypeRemoteSettingsRecord.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 FfiConverterSequenceTypeRemoteSettingsRecord: FfiConverterRustBuffer { typealias SwiftType = [RemoteSettingsRecord] public static func write(_ value: [RemoteSettingsRecord], into buf: inout [UInt8]) { let len = Int32(value.count) writeInt(&buf, len) for item in value { FfiConverterTypeRemoteSettingsRecord.write(item, into: &buf) } } public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [RemoteSettingsRecord] { let len: Int32 = try readInt(&buf) var seq = [RemoteSettingsRecord]() seq.reserveCapacity(Int(len)) for _ in 0 ..< len { seq.append(try FfiConverterTypeRemoteSettingsRecord.read(from: &buf)) } return seq } } #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 FfiConverterDictionaryStringTypeRemoteSettingsRecord: FfiConverterRustBuffer { public static func write(_ value: [String: RemoteSettingsRecord], into buf: inout [UInt8]) { let len = Int32(value.count) writeInt(&buf, len) for (key, value) in value { FfiConverterString.write(key, into: &buf) FfiConverterTypeRemoteSettingsRecord.write(value, into: &buf) } } public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [String: RemoteSettingsRecord] { let len: Int32 = try readInt(&buf) var dict = [String: RemoteSettingsRecord]() dict.reserveCapacity(Int(len)) for _ in 0..<len { let key = try FfiConverterString.read(from: &buf) let value = try FfiConverterTypeRemoteSettingsRecord.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 RsJsonObject = String #if swift(>=5.8) @_documentation(visibility: private) #endif public struct FfiConverterTypeRsJsonObject: FfiConverter { public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> RsJsonObject { return try FfiConverterString.read(from: &buf) } public static func write(_ value: RsJsonObject, into buf: inout [UInt8]) { return FfiConverterString.write(value, into: &buf) } public static func lift(_ value: RustBuffer) throws -> RsJsonObject { return try FfiConverterString.lift(value) } public static func lower(_ value: RsJsonObject) -> RustBuffer { return FfiConverterString.lower(value) } } #if swift(>=5.8) @_documentation(visibility: private) #endif public func FfiConverterTypeRsJsonObject_lift(_ value: RustBuffer) throws -> RsJsonObject { return try FfiConverterTypeRsJsonObject.lift(value) } #if swift(>=5.8) @_documentation(visibility: private) #endif public func FfiConverterTypeRsJsonObject_lower(_ value: RsJsonObject) -> RustBuffer { return FfiConverterTypeRsJsonObject.lower(value) } 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_remote_settings_uniffi_contract_version() if bindings_contract_version != scaffolding_contract_version { return InitializationResult.contractVersionMismatch } if (uniffi_remote_settings_checksum_method_remotesettings_download_attachment_to_path() != 34938) { return InitializationResult.apiChecksumMismatch } if (uniffi_remote_settings_checksum_method_remotesettings_get_records() != 41444) { return InitializationResult.apiChecksumMismatch } if (uniffi_remote_settings_checksum_method_remotesettings_get_records_since() != 58960) { return InitializationResult.apiChecksumMismatch } if (uniffi_remote_settings_checksum_method_remotesettingsclient_collection_name() != 54184) { return InitializationResult.apiChecksumMismatch } if (uniffi_remote_settings_checksum_method_remotesettingsclient_get_attachment() != 1009) { return InitializationResult.apiChecksumMismatch } if (uniffi_remote_settings_checksum_method_remotesettingsclient_get_records() != 64865) { return InitializationResult.apiChecksumMismatch } if (uniffi_remote_settings_checksum_method_remotesettingsclient_get_records_map() != 32665) { return InitializationResult.apiChecksumMismatch } if (uniffi_remote_settings_checksum_method_remotesettingsclient_shutdown() != 43691) { return InitializationResult.apiChecksumMismatch } if (uniffi_remote_settings_checksum_method_remotesettingsclient_sync() != 29749) { return InitializationResult.apiChecksumMismatch } if (uniffi_remote_settings_checksum_method_remotesettingsservice_make_client() != 46337) { return InitializationResult.apiChecksumMismatch } if (uniffi_remote_settings_checksum_method_remotesettingsservice_sync() != 61379) { return InitializationResult.apiChecksumMismatch } if (uniffi_remote_settings_checksum_method_remotesettingsservice_update_config() != 63503) { return InitializationResult.apiChecksumMismatch } if (uniffi_remote_settings_checksum_constructor_remotesettings_new() != 52961) { return InitializationResult.apiChecksumMismatch } if (uniffi_remote_settings_checksum_constructor_remotesettingsservice_new() != 25399) { return InitializationResult.apiChecksumMismatch } 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 uniffiEnsureRemoteSettingsInitialized() { 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