forked from mirrors/gecko-dev
Bug 1851845 - Update vendored Application Services dependencies. r=markh,adw
This commit vendors the latest changes to the Suggest and Remote Settings Rust components. 1. From the `application-services` source tree, I ran `./tools/update-moz-central-vendoring.py ../m-c` to update the revisions in the m-c source tree. 2. I added the Remote Settings component UDL file to `toolkit/components/uniffi-bindgen-gecko-js/mach_commands.py`, and updated `toolkit/components/uniffi-bindgen-gecko-js/config.toml` to call the `RemoteSettings` constructor on the main thread. The Suggest component uses the `RemoteSettingsConfig` type in its public API, so we must generate bindings for the Remote Settings component. 3. From the m-c source tree, I ran `./mach uniffi generate` to update the generated UniFFI bindings. Differential Revision: https://phabricator.services.mozilla.com/D187559
This commit is contained in:
parent
9e56d64a80
commit
1466383668
39 changed files with 3175 additions and 1393 deletions
|
|
@ -70,9 +70,9 @@ git = "https://github.com/mozilla-spidermonkey/jsparagus"
|
|||
rev = "64ba08e24749616de2344112f226d1ef4ba893ae"
|
||||
replace-with = "vendored-sources"
|
||||
|
||||
[source."git+https://github.com/mozilla/application-services?rev=25972c388a4cf3a6d8256504f3a09b711db2fc6a"]
|
||||
[source."git+https://github.com/mozilla/application-services?rev=1a59041d0c7d36ef1abc713a48304c5333e45a1a"]
|
||||
git = "https://github.com/mozilla/application-services"
|
||||
rev = "25972c388a4cf3a6d8256504f3a09b711db2fc6a"
|
||||
rev = "1a59041d0c7d36ef1abc713a48304c5333e45a1a"
|
||||
replace-with = "vendored-sources"
|
||||
|
||||
[source."git+https://github.com/mozilla/audioipc?rev=0b51291d2483a17dce3e300c7784b369e02bee73"]
|
||||
|
|
|
|||
24
Cargo.lock
generated
24
Cargo.lock
generated
|
|
@ -1530,7 +1530,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "error-support"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=25972c388a4cf3a6d8256504f3a09b711db2fc6a#25972c388a4cf3a6d8256504f3a09b711db2fc6a"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=1a59041d0c7d36ef1abc713a48304c5333e45a1a#1a59041d0c7d36ef1abc713a48304c5333e45a1a"
|
||||
dependencies = [
|
||||
"error-support-macros",
|
||||
"lazy_static",
|
||||
|
|
@ -1542,7 +1542,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "error-support-macros"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=25972c388a4cf3a6d8256504f3a09b711db2fc6a#25972c388a4cf3a6d8256504f3a09b711db2fc6a"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=1a59041d0c7d36ef1abc713a48304c5333e45a1a#1a59041d0c7d36ef1abc713a48304c5333e45a1a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -2762,7 +2762,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "interrupt-support"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=25972c388a4cf3a6d8256504f3a09b711db2fc6a#25972c388a4cf3a6d8256504f3a09b711db2fc6a"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=1a59041d0c7d36ef1abc713a48304c5333e45a1a#1a59041d0c7d36ef1abc713a48304c5333e45a1a"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"parking_lot",
|
||||
|
|
@ -3918,7 +3918,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "nss_build_common"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=25972c388a4cf3a6d8256504f3a09b711db2fc6a#25972c388a4cf3a6d8256504f3a09b711db2fc6a"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=1a59041d0c7d36ef1abc713a48304c5333e45a1a#1a59041d0c7d36ef1abc713a48304c5333e45a1a"
|
||||
|
||||
[[package]]
|
||||
name = "nsstring"
|
||||
|
|
@ -4578,7 +4578,7 @@ checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
|
|||
[[package]]
|
||||
name = "remote_settings"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=25972c388a4cf3a6d8256504f3a09b711db2fc6a#25972c388a4cf3a6d8256504f3a09b711db2fc6a"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=1a59041d0c7d36ef1abc713a48304c5333e45a1a#1a59041d0c7d36ef1abc713a48304c5333e45a1a"
|
||||
dependencies = [
|
||||
"parking_lot",
|
||||
"serde",
|
||||
|
|
@ -5095,7 +5095,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "sql-support"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=25972c388a4cf3a6d8256504f3a09b711db2fc6a#25972c388a4cf3a6d8256504f3a09b711db2fc6a"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=1a59041d0c7d36ef1abc713a48304c5333e45a1a#1a59041d0c7d36ef1abc713a48304c5333e45a1a"
|
||||
dependencies = [
|
||||
"ffi-support",
|
||||
"interrupt-support",
|
||||
|
|
@ -5275,7 +5275,7 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
|
|||
[[package]]
|
||||
name = "suggest"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=25972c388a4cf3a6d8256504f3a09b711db2fc6a#25972c388a4cf3a6d8256504f3a09b711db2fc6a"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=1a59041d0c7d36ef1abc713a48304c5333e45a1a#1a59041d0c7d36ef1abc713a48304c5333e45a1a"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"interrupt-support",
|
||||
|
|
@ -5320,7 +5320,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "sync-guid"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=25972c388a4cf3a6d8256504f3a09b711db2fc6a#25972c388a4cf3a6d8256504f3a09b711db2fc6a"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=1a59041d0c7d36ef1abc713a48304c5333e45a1a#1a59041d0c7d36ef1abc713a48304c5333e45a1a"
|
||||
dependencies = [
|
||||
"base64 0.13.999",
|
||||
"rand",
|
||||
|
|
@ -5331,7 +5331,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "sync15"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=25972c388a4cf3a6d8256504f3a09b711db2fc6a#25972c388a4cf3a6d8256504f3a09b711db2fc6a"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=1a59041d0c7d36ef1abc713a48304c5333e45a1a#1a59041d0c7d36ef1abc713a48304c5333e45a1a"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"error-support",
|
||||
|
|
@ -5363,7 +5363,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "tabs"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=25972c388a4cf3a6d8256504f3a09b711db2fc6a#25972c388a4cf3a6d8256504f3a09b711db2fc6a"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=1a59041d0c7d36ef1abc713a48304c5333e45a1a#1a59041d0c7d36ef1abc713a48304c5333e45a1a"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"error-support",
|
||||
|
|
@ -6003,7 +6003,7 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
|||
[[package]]
|
||||
name = "viaduct"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=25972c388a4cf3a6d8256504f3a09b711db2fc6a#25972c388a4cf3a6d8256504f3a09b711db2fc6a"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=1a59041d0c7d36ef1abc713a48304c5333e45a1a#1a59041d0c7d36ef1abc713a48304c5333e45a1a"
|
||||
dependencies = [
|
||||
"ffi-support",
|
||||
"log",
|
||||
|
|
@ -6159,7 +6159,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "webext-storage"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=25972c388a4cf3a6d8256504f3a09b711db2fc6a#25972c388a4cf3a6d8256504f3a09b711db2fc6a"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=1a59041d0c7d36ef1abc713a48304c5333e45a1a#1a59041d0c7d36ef1abc713a48304c5333e45a1a"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"error-support",
|
||||
|
|
|
|||
14
Cargo.toml
14
Cargo.toml
|
|
@ -202,13 +202,13 @@ warp = { git = "https://github.com/glandium/warp", rev = "4af45fae95bc98b0eba1ef
|
|||
malloc_size_of_derive = { path = "xpcom/rust/malloc_size_of_derive" }
|
||||
|
||||
# application-services overrides to make updating them all simpler.
|
||||
interrupt-support = { git = "https://github.com/mozilla/application-services", rev = "25972c388a4cf3a6d8256504f3a09b711db2fc6a" }
|
||||
sql-support = { git = "https://github.com/mozilla/application-services", rev = "25972c388a4cf3a6d8256504f3a09b711db2fc6a" }
|
||||
suggest = { git = "https://github.com/mozilla/application-services", rev = "25972c388a4cf3a6d8256504f3a09b711db2fc6a" }
|
||||
sync15 = { git = "https://github.com/mozilla/application-services", rev = "25972c388a4cf3a6d8256504f3a09b711db2fc6a" }
|
||||
tabs = { git = "https://github.com/mozilla/application-services", rev = "25972c388a4cf3a6d8256504f3a09b711db2fc6a" }
|
||||
viaduct = { git = "https://github.com/mozilla/application-services", rev = "25972c388a4cf3a6d8256504f3a09b711db2fc6a" }
|
||||
webext-storage = { git = "https://github.com/mozilla/application-services", rev = "25972c388a4cf3a6d8256504f3a09b711db2fc6a" }
|
||||
interrupt-support = { git = "https://github.com/mozilla/application-services", rev = "1a59041d0c7d36ef1abc713a48304c5333e45a1a" }
|
||||
sql-support = { git = "https://github.com/mozilla/application-services", rev = "1a59041d0c7d36ef1abc713a48304c5333e45a1a" }
|
||||
suggest = { git = "https://github.com/mozilla/application-services", rev = "1a59041d0c7d36ef1abc713a48304c5333e45a1a" }
|
||||
sync15 = { git = "https://github.com/mozilla/application-services", rev = "1a59041d0c7d36ef1abc713a48304c5333e45a1a" }
|
||||
tabs = { git = "https://github.com/mozilla/application-services", rev = "1a59041d0c7d36ef1abc713a48304c5333e45a1a" }
|
||||
viaduct = { git = "https://github.com/mozilla/application-services", rev = "1a59041d0c7d36ef1abc713a48304c5333e45a1a" }
|
||||
webext-storage = { git = "https://github.com/mozilla/application-services", rev = "1a59041d0c7d36ef1abc713a48304c5333e45a1a" }
|
||||
|
||||
# ICU4X 1.2 with synstructure 0.13.x / syn 2.x. When updating to next version, this should be removed.
|
||||
diplomat = { git = "https://github.com/rust-diplomat/diplomat", rev = "8d125999893fedfdf30595e97334c21ec4b18da9" }
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
{"files":{"Cargo.toml":"c13413955e0ab4939e98e7c0a3eda6d3015734d4764ffa3bc794faf7c975193d","android/build.gradle":"fb6aa2191f1545a92dbcb27552d3da09c19df6612bfa9ae1b70c7d241c50f65b","android/src/main/AndroidManifest.xml":"4c8c9223ad43961108867cf0940b39253c5d4e11ec39c0839a2f137f43ed482a","android/src/test/java/org/mozilla/appservices/remotesettings/RemoteSettingsTest.kt":"d27a6d70cb40607f21c23453d5a53055815ae77c35e59231ee0279787e8932e0","build.rs":"4326f03729cf8f1673e4228e6dc111de1ea4d8bcc06351f7ae563efb2613f866","src/client.rs":"a411e87b485dd3a66202d96c1ef195ba5bdc42fa12d91f9960a64bef2ee5da31","src/config.rs":"7bb678addfae3b4ed5f2892d32263e5b33cc05e5a12a250f664150e78211f94a","src/error.rs":"719a83fb653a8a9a63b26aea7e5fa5210f8a4633d560de92b2b55640715002b2","src/lib.rs":"1daf4dc8265919374b83958f2aa431d44974de44a3ccd926b04d3b0ec207a2cf","src/remote_settings.udl":"06428a5749b04d4f70d704ee561cf30c7f0ad074559b7de0960051a575010b71","uniffi.toml":"f8ec8dc593e0d501c2e9e40368ec93ec33b1edd8608e29495e0a54b63144e880"},"package":null}
|
||||
{"files":{"Cargo.toml":"c74e3df90cd82fb4ee00dd38d7e39cd7a0142ad601b8b63ae214978a28fbe1ac","build.rs":"4326f03729cf8f1673e4228e6dc111de1ea4d8bcc06351f7ae563efb2613f866","src/client.rs":"3d87162e6913a81cc6f5178a7ca791e262d0d029e7dedf3df4fe2f66e5501185","src/config.rs":"7bb678addfae3b4ed5f2892d32263e5b33cc05e5a12a250f664150e78211f94a","src/error.rs":"192ca42af7c6b882f3129378c23b45dab8a0d2b179e23a8813a335ffd56b21dc","src/lib.rs":"416e99894e152f6cea7418ad2fabfd94bc3d907efd9f33fbd2a83fb99452b2df","src/remote_settings.udl":"e38758592ca75adbebb8fe688b10520d9931a5f3292d94f229cba05310756a43","uniffi.toml":"f8ec8dc593e0d501c2e9e40368ec93ec33b1edd8608e29495e0a54b63144e880"},"package":null}
|
||||
2
third_party/rust/remote_settings/Cargo.toml
vendored
2
third_party/rust/remote_settings/Cargo.toml
vendored
|
|
@ -17,6 +17,7 @@ authors = [
|
|||
"The Android Mobile Team <firefox-android-team@mozilla.com>",
|
||||
"The Glean Team <glean-team@mozilla.com>",
|
||||
]
|
||||
exclude = ["/android"]
|
||||
description = "A Remote Settings client intended for application layer platforms."
|
||||
license = "MPL-2.0"
|
||||
|
||||
|
|
@ -32,6 +33,7 @@ url = "2.1"
|
|||
path = "../viaduct"
|
||||
|
||||
[dev-dependencies]
|
||||
expect-test = "1.4"
|
||||
mockito = "0.31"
|
||||
|
||||
[dev-dependencies.viaduct-reqwest]
|
||||
|
|
|
|||
|
|
@ -1,11 +0,0 @@
|
|||
apply from: "$rootDir/build-scripts/component-common.gradle"
|
||||
apply from: "$rootDir/publish.gradle"
|
||||
|
||||
ext.configureUniFFIBindgen("../src/remote_settings.udl")
|
||||
ext.dependsOnTheMegazord()
|
||||
ext.configurePublish()
|
||||
|
||||
dependencies {
|
||||
testImplementation("org.mozilla.components:concept-fetch:$android_components_version")
|
||||
testImplementation project(":httpconfig")
|
||||
}
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.mozilla.appservices.remotesettings" />
|
||||
|
|
@ -1,168 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.appservices.remotesettings
|
||||
|
||||
import mozilla.appservices.httpconfig.RustHttpConfig
|
||||
import mozilla.appservices.remotesettings.RemoteSettings
|
||||
import mozilla.appservices.remotesettings.RemoteSettingsConfig
|
||||
import mozilla.components.concept.fetch.Client
|
||||
import mozilla.components.concept.fetch.Headers
|
||||
import mozilla.components.concept.fetch.MutableHeaders
|
||||
import mozilla.components.concept.fetch.Request
|
||||
import mozilla.components.concept.fetch.Response
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TemporaryFolder
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
import java.io.File
|
||||
import java.io.InputStream
|
||||
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
class RemoteSettingsTest {
|
||||
|
||||
@Rule @JvmField
|
||||
val tempDir = TemporaryFolder()
|
||||
|
||||
private var fakeUrl = ""
|
||||
private var fakeStatus = 200
|
||||
private var fakeHeaders: Headers = MutableHeaders("etag" to "1000")
|
||||
private var fakeBodyStream = "".byteInputStream()
|
||||
private var fakeContentType = ""
|
||||
private var fakeBody = Response.Body(fakeBodyStream, fakeContentType)
|
||||
private var doFetch: (Request) -> Response = {
|
||||
Response(fakeUrl, fakeStatus, fakeHeaders, fakeBody)
|
||||
}
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
RustHttpConfig.setClient(
|
||||
lazyOf(object : Client() {
|
||||
override fun fetch(request: Request): Response = doFetch(request)
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test setting up, fetching records, and attachment downloading`() {
|
||||
val config = RemoteSettingsConfig(
|
||||
serverUrl = "http://localhost:8888",
|
||||
bucketName = "the-bucket",
|
||||
collectionName = "the-collection",
|
||||
)
|
||||
|
||||
// Setup the client
|
||||
val client = RemoteSettings(config)
|
||||
|
||||
// Fetch the records
|
||||
setupRecordResponse(config, responseBodyStream = recordJson.byteInputStream())
|
||||
val response = client.getRecords()
|
||||
val records = response.records
|
||||
assertEquals(records[0].fields.getString("title"), recordTitle)
|
||||
|
||||
// Download an attachment
|
||||
val attachmentLocation = records[0].attachment!!.location
|
||||
val localAttachmentPath = "${tempDir.root}/path.jpg"
|
||||
setupAttachmentResponses(config, attachmentLocation)
|
||||
client.downloadAttachmentToPath(attachmentLocation, localAttachmentPath)
|
||||
val downloadedFile = File(localAttachmentPath)
|
||||
assertTrue(downloadedFile.exists())
|
||||
assertEquals(csv, downloadedFile.readText())
|
||||
}
|
||||
|
||||
private fun setupAttachmentResponses(
|
||||
config: RemoteSettingsConfig,
|
||||
attachmentLocation: String,
|
||||
) {
|
||||
val topUrl = config.serverUrl
|
||||
val attachmentUrl = "${config.serverUrl}/attachments/$attachmentLocation"
|
||||
doFetch = { req ->
|
||||
when (req.url) {
|
||||
"$topUrl/" -> {
|
||||
Response(
|
||||
url = req.url,
|
||||
status = 200,
|
||||
headers = fakeHeaders,
|
||||
body = Response.Body(
|
||||
stream = attachmentsInfoJson(topUrl!!).byteInputStream(),
|
||||
null,
|
||||
),
|
||||
)
|
||||
}
|
||||
attachmentUrl -> {
|
||||
Response(
|
||||
url = attachmentUrl,
|
||||
status = 200,
|
||||
headers = fakeHeaders,
|
||||
body = Response.Body(
|
||||
stream = csv.byteInputStream(),
|
||||
null,
|
||||
),
|
||||
)
|
||||
}
|
||||
else -> error("unexpected url")
|
||||
}
|
||||
}
|
||||
}
|
||||
private fun setupRecordResponse(
|
||||
config: RemoteSettingsConfig,
|
||||
responseBodyStream: InputStream = recordJson.byteInputStream(),
|
||||
) {
|
||||
fakeUrl = "${config.serverUrl}/v1/buckets/${config.bucketName}/collections/${config.collectionName}/records"
|
||||
fakeBody = Response.Body(responseBodyStream, null)
|
||||
}
|
||||
|
||||
private fun attachmentsInfoJson(baseUrl: String) = """
|
||||
{
|
||||
"capabilities": {
|
||||
"admin": {
|
||||
"description": "Serves the admin console.",
|
||||
"url": "https://github.com/Kinto/kinto-admin/",
|
||||
"version": "2.0.0"
|
||||
},
|
||||
"attachments": {
|
||||
"description": "Add file attachments to records",
|
||||
"url": "https://github.com/Kinto/kinto-attachment/",
|
||||
"version": "6.3.1",
|
||||
"base_url": "$baseUrl/attachments/"
|
||||
}
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
|
||||
private val recordTitle = "with-txt-attachment"
|
||||
private val recordJson = """
|
||||
{
|
||||
"data": [
|
||||
{
|
||||
"title": "$recordTitle",
|
||||
"content": "content",
|
||||
"attachment": {
|
||||
"filename": "text-attachment.csv",
|
||||
"location": "the-bucket/the-collection/d3a5eccc-f0ca-42c3-b0bb-c0d4408c21c9.jpg",
|
||||
"hash": "2cbd593f3fd5f1585f92265433a6696a863bc98726f03e7222135ff0d8e83543",
|
||||
"mimetype": "text/csv",
|
||||
"size": 1374325
|
||||
},
|
||||
"schema": 1677694447771,
|
||||
"id": "7403c6f9-79be-4e0c-a37a-8f2b5bd7ad58",
|
||||
"last_modified": 1677694455368
|
||||
}
|
||||
]
|
||||
}
|
||||
""".trimIndent()
|
||||
|
||||
private val csv = """
|
||||
John,Doe,120 jefferson st.,Riverside, NJ, 08075
|
||||
Jack,McGinnis,220 hobo Av.,Phila, PA,09119
|
||||
"John ""Da Man""${'"'},Repici,120 Jefferson St.,Riverside, NJ,08075
|
||||
Stephen,Tyler,"7452 Terrace ""At the Plaza"" road",SomeTown,SD, 91234
|
||||
,Blankman,,SomeTown, SD, 00298
|
||||
"Joan ""the bone"", Anne",Jet,"9th, at Terrace plc",Desert City,CO,00123
|
||||
""".trimIndent()
|
||||
}
|
||||
356
third_party/rust/remote_settings/src/client.rs
vendored
356
third_party/rust/remote_settings/src/client.rs
vendored
|
|
@ -15,6 +15,7 @@ use url::Url;
|
|||
use viaduct::{Request, Response};
|
||||
|
||||
const HEADER_BACKOFF: &str = "Backoff";
|
||||
const HEADER_ETAG: &str = "ETag";
|
||||
const HEADER_RETRY_AFTER: &str = "Retry-After";
|
||||
|
||||
/// A simple HTTP client that can retrieve Remote Settings data using the properties by [ClientConfig].
|
||||
|
|
@ -48,16 +49,7 @@ impl Client {
|
|||
/// bucket, and collection defined by the [ClientConfig] used to generate
|
||||
/// this [Client].
|
||||
pub fn get_records(&self) -> Result<RemoteSettingsResponse> {
|
||||
let resp = self.get_records_raw()?;
|
||||
let records = resp.json::<RecordsResponse>()?.data;
|
||||
let last_modified = resp
|
||||
.headers
|
||||
.get_as("etag")
|
||||
.ok_or_else(|| RemoteSettingsError::ResponseError("no etag header".into()))??;
|
||||
Ok(RemoteSettingsResponse {
|
||||
records,
|
||||
last_modified,
|
||||
})
|
||||
self.get_records_with_options(&GetItemsOptions::new())
|
||||
}
|
||||
|
||||
/// Fetches all records for a collection that can be found in the server,
|
||||
|
|
@ -71,14 +63,31 @@ impl Client {
|
|||
/// for a collection that can be found in the server, bucket, and
|
||||
/// collection defined by the [ClientConfig] used to generate this [Client].
|
||||
pub fn get_records_since(&self, timestamp: u64) -> Result<RemoteSettingsResponse> {
|
||||
let resp = self.get_records_raw_with_options(
|
||||
self.get_records_with_options(
|
||||
GetItemsOptions::new().gt("last_modified", timestamp.to_string()),
|
||||
)?;
|
||||
)
|
||||
}
|
||||
|
||||
/// Fetches records from this client's collection with the given options.
|
||||
pub fn get_records_with_options(
|
||||
&self,
|
||||
options: &GetItemsOptions,
|
||||
) -> Result<RemoteSettingsResponse> {
|
||||
let resp = self.get_records_raw_with_options(options)?;
|
||||
let records = resp.json::<RecordsResponse>()?.data;
|
||||
let last_modified = resp
|
||||
let etag = resp
|
||||
.headers
|
||||
.get_as("etag")
|
||||
.ok_or_else(|| RemoteSettingsError::ResponseError("no etag header".into()))??;
|
||||
.get(HEADER_ETAG)
|
||||
.ok_or_else(|| RemoteSettingsError::ResponseError("no etag header".into()))?;
|
||||
// Per https://docs.kinto-storage.org/en/stable/api/1.x/timestamps.html,
|
||||
// the `ETag` header value is a quoted integer. Trim the quotes before
|
||||
// parsing.
|
||||
let last_modified = etag.trim_matches('"').parse().map_err(|_| {
|
||||
RemoteSettingsError::ResponseError(format!(
|
||||
"expected quoted integer in etag header; got `{}`",
|
||||
etag
|
||||
))
|
||||
})?;
|
||||
Ok(RemoteSettingsResponse {
|
||||
records,
|
||||
last_modified,
|
||||
|
|
@ -102,22 +111,32 @@ impl Client {
|
|||
/// Downloads an attachment from [attachment_location]. NOTE: there are no
|
||||
/// guarantees about a maximum size, so use care when fetching potentially
|
||||
/// large attachments.
|
||||
pub fn get_attachment(&self, attachment_location: &str) -> Result<Response> {
|
||||
let mut current_remote_state = self.remote_state.lock();
|
||||
self.ensure_no_backoff(&mut current_remote_state.backoff)?;
|
||||
let attachments_base_url = match ¤t_remote_state.attachments_base_url {
|
||||
Some(url) => url.clone(),
|
||||
pub fn get_attachment(&self, attachment_location: &str) -> Result<Vec<u8>> {
|
||||
Ok(self.get_attachment_raw(attachment_location)?.body)
|
||||
}
|
||||
|
||||
/// Fetches a raw network [Response] for an attachment.
|
||||
pub fn get_attachment_raw(&self, attachment_location: &str) -> Result<Response> {
|
||||
// Important: We use a `let` binding here to ensure that the mutex is
|
||||
// unlocked immediately after cloning the URL. If we matched directly on
|
||||
// the `.lock()` expression, the mutex would stay locked until the end
|
||||
// of the `match`, causing a deadlock.
|
||||
let maybe_attachments_base_url = self.remote_state.lock().attachments_base_url.clone();
|
||||
|
||||
let attachments_base_url = match maybe_attachments_base_url {
|
||||
Some(attachments_base_url) => attachments_base_url,
|
||||
None => {
|
||||
let req = Request::get(self.base_url.clone());
|
||||
let server_info = req.send()?.json::<ServerInfo>()?;
|
||||
match server_info.capabilities.attachments {
|
||||
let server_info = self
|
||||
.make_request(self.base_url.clone())?
|
||||
.json::<ServerInfo>()?;
|
||||
let attachments_base_url = match server_info.capabilities.attachments {
|
||||
Some(capability) => Url::parse(&capability.base_url)?,
|
||||
None => Err(RemoteSettingsError::AttachmentsUnsupportedError)?,
|
||||
}
|
||||
};
|
||||
self.remote_state.lock().attachments_base_url = Some(attachments_base_url.clone());
|
||||
attachments_base_url
|
||||
}
|
||||
};
|
||||
current_remote_state.attachments_base_url = Some(attachments_base_url.clone());
|
||||
drop(current_remote_state);
|
||||
|
||||
self.make_request(attachments_base_url.join(attachment_location)?)
|
||||
}
|
||||
|
|
@ -187,6 +206,7 @@ impl Client {
|
|||
|
||||
/// Data structure representing the top-level response from the Remote Settings.
|
||||
/// [last_modified] will be extracted from the etag header of the response.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct RemoteSettingsResponse {
|
||||
pub records: Vec<RemoteSettingsRecord>,
|
||||
pub last_modified: u64,
|
||||
|
|
@ -203,6 +223,8 @@ struct RecordsResponse {
|
|||
pub struct RemoteSettingsRecord {
|
||||
pub id: String,
|
||||
pub last_modified: u64,
|
||||
#[serde(default)]
|
||||
pub deleted: bool,
|
||||
pub attachment: Option<Attachment>,
|
||||
#[serde(flatten)]
|
||||
pub fields: RsJsonObject,
|
||||
|
|
@ -485,6 +507,7 @@ impl Sort {
|
|||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use expect_test::expect;
|
||||
use mockito::{mock, Matcher};
|
||||
#[test]
|
||||
fn test_defaults() {
|
||||
|
|
@ -528,11 +551,13 @@ mod test {
|
|||
};
|
||||
|
||||
let client = Client::new(config).unwrap();
|
||||
let resp = client.get_attachment(attachment_location).unwrap();
|
||||
let first_resp = client.get_attachment(attachment_location).unwrap();
|
||||
let second_resp = client.get_attachment(attachment_location).unwrap();
|
||||
|
||||
server_info_m.expect(1).assert();
|
||||
attachment_m.expect(1).assert();
|
||||
assert_eq!(resp.body, attachment_bytes);
|
||||
attachment_m.expect(2).assert();
|
||||
assert_eq!(first_resp, attachment_bytes);
|
||||
assert_eq!(second_resp, attachment_bytes);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -582,7 +607,7 @@ mod test {
|
|||
.with_status(200)
|
||||
.with_header("content-type", "application/json")
|
||||
.with_header("Backoff", "60")
|
||||
.with_header("etag", "1000")
|
||||
.with_header("etag", "\"1000\"")
|
||||
.create();
|
||||
let config = RemoteSettingsConfig {
|
||||
server_url: Some(mockito::server_url()),
|
||||
|
|
@ -651,7 +676,7 @@ mod test {
|
|||
.with_body(response_body())
|
||||
.with_status(200)
|
||||
.with_header("content-type", "application/json")
|
||||
.with_header("etag", "1000")
|
||||
.with_header("etag", "\"1000\"")
|
||||
.create();
|
||||
let config = RemoteSettingsConfig {
|
||||
server_url: Some(mockito::server_url()),
|
||||
|
|
@ -659,9 +684,8 @@ mod test {
|
|||
bucket_name: Some(String::from("the-bucket")),
|
||||
};
|
||||
let http_client = Client::new(config).unwrap();
|
||||
assert!(http_client
|
||||
.get_records_raw_with_options(
|
||||
GetItemsOptions::new()
|
||||
let mut options = GetItemsOptions::new();
|
||||
options
|
||||
.field("a")
|
||||
.field("c")
|
||||
.field("b")
|
||||
|
|
@ -677,10 +701,93 @@ mod test {
|
|||
.contains("n", "o")
|
||||
.sort("b", SortOrder::Descending)
|
||||
.sort("a", SortOrder::Ascending)
|
||||
.limit(3)
|
||||
)
|
||||
.is_ok());
|
||||
m.expect(1).assert();
|
||||
.limit(3);
|
||||
|
||||
assert!(http_client.get_records_raw_with_options(&options).is_ok());
|
||||
expect![[r#"
|
||||
RemoteSettingsResponse {
|
||||
records: [
|
||||
RemoteSettingsRecord {
|
||||
id: "c5dcd1da-7126-4abb-846b-ec85b0d4d0d7",
|
||||
last_modified: 1677694949407,
|
||||
deleted: false,
|
||||
attachment: Some(
|
||||
Attachment {
|
||||
filename: "jgp-attachment.jpg",
|
||||
mimetype: "image/jpeg",
|
||||
location: "the-bucket/the-collection/d3a5eccc-f0ca-42c3-b0bb-c0d4408c21c9.jpg",
|
||||
hash: "2cbd593f3fd5f1585f92265433a6696a863bc98726f03e7222135ff0d8e83543",
|
||||
size: 1374325,
|
||||
},
|
||||
),
|
||||
fields: {
|
||||
"content": String(
|
||||
"content",
|
||||
),
|
||||
"schema": Number(
|
||||
1677694447771,
|
||||
),
|
||||
"title": String(
|
||||
"jpg-attachment",
|
||||
),
|
||||
},
|
||||
},
|
||||
RemoteSettingsRecord {
|
||||
id: "ff301910-6bf5-4cfe-bc4c-5c80308661a5",
|
||||
last_modified: 1677694470354,
|
||||
deleted: false,
|
||||
attachment: Some(
|
||||
Attachment {
|
||||
filename: "pdf-attachment.pdf",
|
||||
mimetype: "application/pdf",
|
||||
location: "the-bucket/the-collection/5f7347c2-af92-411d-a65b-f794f9b5084c.pdf",
|
||||
hash: "de1cde3571ef3faa77ea0493276de9231acaa6f6651602e93aa1036f51181e9b",
|
||||
size: 157,
|
||||
},
|
||||
),
|
||||
fields: {
|
||||
"content": String(
|
||||
"content",
|
||||
),
|
||||
"schema": Number(
|
||||
1677694447771,
|
||||
),
|
||||
"title": String(
|
||||
"with-attachment",
|
||||
),
|
||||
},
|
||||
},
|
||||
RemoteSettingsRecord {
|
||||
id: "7403c6f9-79be-4e0c-a37a-8f2b5bd7ad58",
|
||||
last_modified: 1677694455368,
|
||||
deleted: false,
|
||||
attachment: None,
|
||||
fields: {
|
||||
"content": String(
|
||||
"content",
|
||||
),
|
||||
"schema": Number(
|
||||
1677694447771,
|
||||
),
|
||||
"title": String(
|
||||
"no-attachment",
|
||||
),
|
||||
},
|
||||
},
|
||||
RemoteSettingsRecord {
|
||||
id: "9320f53c-0a39-4997-9120-62ff597ffb26",
|
||||
last_modified: 1690921847416,
|
||||
deleted: true,
|
||||
attachment: None,
|
||||
fields: {},
|
||||
},
|
||||
],
|
||||
last_modified: 1000,
|
||||
}
|
||||
"#]].assert_debug_eq(&http_client
|
||||
.get_records_with_options(&options)
|
||||
.unwrap());
|
||||
m.expect(2).assert();
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -693,7 +800,7 @@ mod test {
|
|||
.with_body(response_body())
|
||||
.with_status(200)
|
||||
.with_header("content-type", "application/json")
|
||||
.with_header("etag", "1000")
|
||||
.with_header("etag", "\"1000\"")
|
||||
.create();
|
||||
let config = RemoteSettingsConfig {
|
||||
server_url: Some(mockito::server_url()),
|
||||
|
|
@ -723,6 +830,166 @@ mod test {
|
|||
m.expect(1).assert();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_record_fields() {
|
||||
viaduct_reqwest::use_reqwest_backend();
|
||||
let m = mock(
|
||||
"GET",
|
||||
"/v1/buckets/the-bucket/collections/the-collection/records",
|
||||
)
|
||||
.with_body(response_body())
|
||||
.with_status(200)
|
||||
.with_header("content-type", "application/json")
|
||||
.with_header("etag", "\"1000\"")
|
||||
.create();
|
||||
let config = RemoteSettingsConfig {
|
||||
server_url: Some(mockito::server_url()),
|
||||
collection_name: String::from("the-collection"),
|
||||
bucket_name: Some(String::from("the-bucket")),
|
||||
};
|
||||
let http_client = Client::new(config).unwrap();
|
||||
let response = http_client.get_records().unwrap();
|
||||
expect![[r#"
|
||||
RemoteSettingsResponse {
|
||||
records: [
|
||||
RemoteSettingsRecord {
|
||||
id: "c5dcd1da-7126-4abb-846b-ec85b0d4d0d7",
|
||||
last_modified: 1677694949407,
|
||||
deleted: false,
|
||||
attachment: Some(
|
||||
Attachment {
|
||||
filename: "jgp-attachment.jpg",
|
||||
mimetype: "image/jpeg",
|
||||
location: "the-bucket/the-collection/d3a5eccc-f0ca-42c3-b0bb-c0d4408c21c9.jpg",
|
||||
hash: "2cbd593f3fd5f1585f92265433a6696a863bc98726f03e7222135ff0d8e83543",
|
||||
size: 1374325,
|
||||
},
|
||||
),
|
||||
fields: {
|
||||
"content": String(
|
||||
"content",
|
||||
),
|
||||
"schema": Number(
|
||||
1677694447771,
|
||||
),
|
||||
"title": String(
|
||||
"jpg-attachment",
|
||||
),
|
||||
},
|
||||
},
|
||||
RemoteSettingsRecord {
|
||||
id: "ff301910-6bf5-4cfe-bc4c-5c80308661a5",
|
||||
last_modified: 1677694470354,
|
||||
deleted: false,
|
||||
attachment: Some(
|
||||
Attachment {
|
||||
filename: "pdf-attachment.pdf",
|
||||
mimetype: "application/pdf",
|
||||
location: "the-bucket/the-collection/5f7347c2-af92-411d-a65b-f794f9b5084c.pdf",
|
||||
hash: "de1cde3571ef3faa77ea0493276de9231acaa6f6651602e93aa1036f51181e9b",
|
||||
size: 157,
|
||||
},
|
||||
),
|
||||
fields: {
|
||||
"content": String(
|
||||
"content",
|
||||
),
|
||||
"schema": Number(
|
||||
1677694447771,
|
||||
),
|
||||
"title": String(
|
||||
"with-attachment",
|
||||
),
|
||||
},
|
||||
},
|
||||
RemoteSettingsRecord {
|
||||
id: "7403c6f9-79be-4e0c-a37a-8f2b5bd7ad58",
|
||||
last_modified: 1677694455368,
|
||||
deleted: false,
|
||||
attachment: None,
|
||||
fields: {
|
||||
"content": String(
|
||||
"content",
|
||||
),
|
||||
"schema": Number(
|
||||
1677694447771,
|
||||
),
|
||||
"title": String(
|
||||
"no-attachment",
|
||||
),
|
||||
},
|
||||
},
|
||||
RemoteSettingsRecord {
|
||||
id: "9320f53c-0a39-4997-9120-62ff597ffb26",
|
||||
last_modified: 1690921847416,
|
||||
deleted: true,
|
||||
attachment: None,
|
||||
fields: {},
|
||||
},
|
||||
],
|
||||
last_modified: 1000,
|
||||
}
|
||||
"#]].assert_debug_eq(&response);
|
||||
m.expect(1).assert();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_missing_etag() {
|
||||
viaduct_reqwest::use_reqwest_backend();
|
||||
let m = mock(
|
||||
"GET",
|
||||
"/v1/buckets/the-bucket/collections/the-collection/records",
|
||||
)
|
||||
.with_body(response_body())
|
||||
.with_status(200)
|
||||
.with_header("content-type", "application/json")
|
||||
.create();
|
||||
|
||||
let config = RemoteSettingsConfig {
|
||||
server_url: Some(mockito::server_url()),
|
||||
bucket_name: Some(String::from("the-bucket")),
|
||||
collection_name: String::from("the-collection"),
|
||||
};
|
||||
let client = Client::new(config).unwrap();
|
||||
|
||||
let err = client.get_records().unwrap_err();
|
||||
assert!(
|
||||
matches!(err, RemoteSettingsError::ResponseError(_)),
|
||||
"Want response error for missing `ETag`; got {}",
|
||||
err
|
||||
);
|
||||
m.expect(1).assert();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_etag() {
|
||||
viaduct_reqwest::use_reqwest_backend();
|
||||
let m = mock(
|
||||
"GET",
|
||||
"/v1/buckets/the-bucket/collections/the-collection/records",
|
||||
)
|
||||
.with_body(response_body())
|
||||
.with_status(200)
|
||||
.with_header("content-type", "application/json")
|
||||
.with_header("etag", "bad!")
|
||||
.create();
|
||||
|
||||
let config = RemoteSettingsConfig {
|
||||
server_url: Some(mockito::server_url()),
|
||||
bucket_name: Some(String::from("the-bucket")),
|
||||
collection_name: String::from("the-collection"),
|
||||
};
|
||||
let client = Client::new(config).unwrap();
|
||||
|
||||
let err = client.get_records().unwrap_err();
|
||||
assert!(
|
||||
matches!(err, RemoteSettingsError::ResponseError(_)),
|
||||
"Want response error for invalid `ETag`; got {}",
|
||||
err
|
||||
);
|
||||
m.expect(1).assert();
|
||||
}
|
||||
|
||||
fn attachment_metadata(base_url: String) -> String {
|
||||
format!(
|
||||
r#"
|
||||
|
|
@ -763,12 +1030,13 @@ mod test {
|
|||
r#"
|
||||
{{
|
||||
"data": [
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{}
|
||||
]
|
||||
}}"#,
|
||||
JPG_ATTACHMENT, PDF_ATTACHMENT, NO_ATTACHMENT
|
||||
JPG_ATTACHMENT, PDF_ATTACHMENT, NO_ATTACHMENT, TOMBSTONE
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -815,4 +1083,12 @@ mod test {
|
|||
"last_modified": 1677694455368
|
||||
}
|
||||
"#;
|
||||
|
||||
const TOMBSTONE: &str = r#"
|
||||
{
|
||||
"id": "9320f53c-0a39-4997-9120-62ff597ffb26",
|
||||
"last_modified": 1690921847416,
|
||||
"deleted": true
|
||||
}
|
||||
"#;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,8 +8,6 @@ pub enum RemoteSettingsError {
|
|||
JSONError(#[from] serde_json::Error),
|
||||
#[error("Error writing downloaded attachment: {0}")]
|
||||
FileError(#[from] std::io::Error),
|
||||
#[error("ParseIntError: {0}")]
|
||||
ParseIntError(#[from] std::num::ParseIntError),
|
||||
/// An error has occured while sending a request.
|
||||
#[error("Error sending request: {0}")]
|
||||
RequestError(#[from] viaduct::Error),
|
||||
|
|
|
|||
6
third_party/rust/remote_settings/src/lib.rs
vendored
6
third_party/rust/remote_settings/src/lib.rs
vendored
|
|
@ -45,7 +45,7 @@ impl RemoteSettings {
|
|||
) -> Result<()> {
|
||||
let resp = self.client.get_attachment(&attachment_location)?;
|
||||
let mut file = File::create(path)?;
|
||||
file.write_all(&resp.body)?;
|
||||
file.write_all(&resp)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
@ -66,7 +66,7 @@ mod test {
|
|||
.with_body(response_body())
|
||||
.with_status(200)
|
||||
.with_header("content-type", "application/json")
|
||||
.with_header("etag", "1000")
|
||||
.with_header("etag", "\"1000\"")
|
||||
.create();
|
||||
|
||||
let config = RemoteSettingsConfig {
|
||||
|
|
@ -94,7 +94,7 @@ mod test {
|
|||
.with_body(response_body())
|
||||
.with_status(200)
|
||||
.with_header("content-type", "application/json")
|
||||
.with_header("etag", "1000")
|
||||
.with_header("etag", "\"1000\"")
|
||||
.create();
|
||||
|
||||
let config = RemoteSettingsConfig {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ dictionary RemoteSettingsResponse {
|
|||
dictionary RemoteSettingsRecord {
|
||||
string id;
|
||||
u64 last_modified;
|
||||
boolean deleted;
|
||||
Attachment? attachment;
|
||||
RsJsonObject fields;
|
||||
};
|
||||
|
|
@ -37,7 +38,6 @@ dictionary Attachment {
|
|||
enum RemoteSettingsError {
|
||||
"JSONError",
|
||||
"FileError",
|
||||
"ParseIntError",
|
||||
"RequestError",
|
||||
"UrlParsingError",
|
||||
"BackoffError",
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
{"files":{"Cargo.toml":"e679992b7cf7d42cdbc5d6350c512ca448a273767003db600ef8099c7182bd99","build.rs":"d89f20669c2e243652630ce025199d187d2a128be6a626a02e0679bd74a2ad5a","src/conn_ext.rs":"e48e862e47c000c545dcc766fc1889498a8709bee00e240ed68d247b0fbef577","src/debug_tools.rs":"bece2bc3d35379b81ea2f942a0a3e909e0ab0553656505904745548eacaf402a","src/each_chunk.rs":"8aaba842e43b002fbc0fee95d14ce08faa7187b1979c765b2e270cd4802607a5","src/lib.rs":"af704ec04beb6c2c388d4566710e1167b18fb64acb248ccf37a67679daffddb6","src/maybe_cached.rs":"0b18425595055883a98807fbd62ff27a79c18af34e7cb3439f8c3438463ef2dd","src/open_database.rs":"dcc7140095f9ba20442b5e6294d8af924d54588837cf2ce019dff013fa198783","src/repeat.rs":"b4c5ff5d083afba7f9f153f54aba2e6859b78b85c82d48dbd6bd58f67da9e6b9"},"package":null}
|
||||
{"files":{"Cargo.toml":"e679992b7cf7d42cdbc5d6350c512ca448a273767003db600ef8099c7182bd99","build.rs":"d89f20669c2e243652630ce025199d187d2a128be6a626a02e0679bd74a2ad5a","src/conn_ext.rs":"e48e862e47c000c545dcc766fc1889498a8709bee00e240ed68d247b0fbef577","src/debug_tools.rs":"bece2bc3d35379b81ea2f942a0a3e909e0ab0553656505904745548eacaf402a","src/each_chunk.rs":"8aaba842e43b002fbc0fee95d14ce08faa7187b1979c765b2e270cd4802607a5","src/lib.rs":"af704ec04beb6c2c388d4566710e1167b18fb64acb248ccf37a67679daffddb6","src/maybe_cached.rs":"0b18425595055883a98807fbd62ff27a79c18af34e7cb3439f8c3438463ef2dd","src/open_database.rs":"40ad2da7d5559f0e5180e35d403c307ce230fe9d0d2a3fec7c9481ce13acda64","src/repeat.rs":"b4c5ff5d083afba7f9f153f54aba2e6859b78b85c82d48dbd6bd58f67da9e6b9"},"package":null}
|
||||
|
|
@ -22,6 +22,8 @@
|
|||
/// it and call prepare(), upgrade_from() for each upgrade that needs to be applied, then
|
||||
/// finish(). As above, a read-only connection will panic if upgrades are necessary, so
|
||||
/// you should ensure the first connection opened is writable.
|
||||
/// - If the database file is corrupt, or upgrade_from() returns [`Error::Corrupt`], the
|
||||
/// database file will be removed and replaced with a new DB.
|
||||
/// - If the connection is not writable, `finish()` will be called (ie, `finish()`, like
|
||||
/// `prepare()`, is called for all connections)
|
||||
///
|
||||
|
|
@ -38,11 +40,25 @@ use thiserror::Error;
|
|||
pub enum Error {
|
||||
#[error("Incompatible database version: {0}")]
|
||||
IncompatibleVersion(u32),
|
||||
#[error("Database is corrupt")]
|
||||
Corrupt,
|
||||
#[error("Error executing SQL: {0}")]
|
||||
SqlError(#[from] rusqlite::Error),
|
||||
// `.0` is the original `Error` in string form.
|
||||
#[error("Failed to recover a corrupt database ('{0}') due to an error deleting the file: {1}")]
|
||||
RecoveryError(String, std::io::Error),
|
||||
SqlError(rusqlite::Error),
|
||||
#[error("Failed to recover a corrupt database due to an error deleting the file: {0}")]
|
||||
RecoveryError(std::io::Error),
|
||||
}
|
||||
|
||||
impl From<rusqlite::Error> for Error {
|
||||
fn from(value: rusqlite::Error) -> Self {
|
||||
match value {
|
||||
RusqliteError::SqliteFailure(e, _)
|
||||
if matches!(e.code, ErrorCode::DatabaseCorrupt | ErrorCode::NotADatabase) =>
|
||||
{
|
||||
Self::Corrupt
|
||||
}
|
||||
_ => Self::SqlError(value),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
|
@ -189,12 +205,7 @@ fn try_handle_db_failure<CI: ConnectionInitializer, P: AsRef<Path>>(
|
|||
return Err(err);
|
||||
}
|
||||
|
||||
let delete = match err {
|
||||
Error::SqlError(RusqliteError::SqliteFailure(e, _)) => {
|
||||
matches!(e.code, ErrorCode::DatabaseCorrupt | ErrorCode::NotADatabase)
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
let delete = matches!(err, Error::Corrupt);
|
||||
if delete {
|
||||
log::info!(
|
||||
"{}: the database is fatally damaged; deleting and starting fresh",
|
||||
|
|
@ -204,7 +215,7 @@ fn try_handle_db_failure<CI: ConnectionInitializer, P: AsRef<Path>>(
|
|||
// identify any value there - actually getting our hands on the file from a mobile device
|
||||
// is tricky and it would just take up disk space forever.
|
||||
if let Err(io_err) = std::fs::remove_file(path) {
|
||||
return Err(Error::RecoveryError(err.to_string(), io_err));
|
||||
return Err(Error::RecoveryError(io_err));
|
||||
}
|
||||
Ok(())
|
||||
} else {
|
||||
|
|
@ -364,6 +375,12 @@ mod test {
|
|||
|
||||
fn upgrade_from(&self, conn: &Transaction<'_>, version: u32) -> Result<()> {
|
||||
match version {
|
||||
// This upgrade forces the database to be replaced by returning
|
||||
// `Error::Corrupt`.
|
||||
1 => {
|
||||
self.push_call("upgrade_from_v1");
|
||||
Err(Error::Corrupt)
|
||||
}
|
||||
2 => {
|
||||
self.push_call("upgrade_from_v2");
|
||||
conn.execute_batch(
|
||||
|
|
@ -404,6 +421,13 @@ mod test {
|
|||
}
|
||||
}
|
||||
|
||||
// A special schema used to test the upgrade that forces the database to be
|
||||
// replaced.
|
||||
static INIT_V1: &str = "
|
||||
CREATE TABLE prep_table(col);
|
||||
PRAGMA user_version=1;
|
||||
";
|
||||
|
||||
// Initialize the database to v2 to test upgrading from there
|
||||
static INIT_V2: &str = "
|
||||
CREATE TABLE prep_table(col);
|
||||
|
|
@ -533,4 +557,18 @@ mod test {
|
|||
// just check the file is no longer what it was before.
|
||||
assert_ne!(metadata.len(), 7);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_force_replace() {
|
||||
let db_file = MigratedDatabaseFile::new(TestConnectionInitializer::new(), INIT_V1);
|
||||
let conn = open_database(db_file.path.clone(), &db_file.connection_initializer).unwrap();
|
||||
check_final_data(&conn);
|
||||
db_file.connection_initializer.check_calls(vec![
|
||||
"prep",
|
||||
"upgrade_from_v1",
|
||||
"prep",
|
||||
"init",
|
||||
"finish",
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
{"files":{"Cargo.toml":"2a7334dc6420c7f7d1c14affaee132fb355e96ae94463153db72d7d5a316efd7","README.md":"8d7457893194e255b87e5a2667ee25c87bd470f5338d7078506f866a67a3fdbd","build.rs":"78780c5cccfe22c3ff4198624b9e188559c437c3e6fa1c8bb66548eee6aa66bf","src/db.rs":"9ad7fe53861ccfa01ccda1aa2132154a7967f7ef729709a52c940a4ea9ab2539","src/error.rs":"f47763a1a5d228b446eb8f718433e49fdb1c7b304de1255891215144dddd7a43","src/keyword.rs":"988d0ab021c0df19cfd3c519df7d37f606bf984cd14d0efca4e5a7aff88344dd","src/lib.rs":"831fd8e3881be06c560d502357188d143a2774e19b371cc40c40c2378810297b","src/rs.rs":"9e8e937306615c1e173143083d4a5b526a1c0c2b28092305ecd4dfe6c665f851","src/schema.rs":"962b9f5916089d6656de77afcc81e51cb81310f8dbcb9bbaa248b26a1d087332","src/store.rs":"d04edba77295f3a96af18668a1851fd1b4afe5ae449b8b1a14cd47e25151fd51","src/suggest.udl":"8035e6261e55d5e37366f219f5806b842cc2f91dffd39e3ba9bfa9484e22fd6c","uniffi.toml":"fb8add80c2f660e4eacf95ec3f0b1d0f6a92ab5dbcf607782350442814ee26a7"},"package":null}
|
||||
{"files":{"Cargo.toml":"7c19ff48428dd00ea709c254f1aa44627dd5d0f30d0741285f27a6f4a6200e1f","README.md":"8d7457893194e255b87e5a2667ee25c87bd470f5338d7078506f866a67a3fdbd","build.rs":"78780c5cccfe22c3ff4198624b9e188559c437c3e6fa1c8bb66548eee6aa66bf","src/db.rs":"f40754ac33ff111b5165ed271064de8248acd2d39ac67aed92cbbda2826f45fe","src/error.rs":"f47763a1a5d228b446eb8f718433e49fdb1c7b304de1255891215144dddd7a43","src/keyword.rs":"988d0ab021c0df19cfd3c519df7d37f606bf984cd14d0efca4e5a7aff88344dd","src/lib.rs":"1294435de3ed1de26f7fe7e9a5760bcb1fe06c9c51f308c1f63666f96ba59ae5","src/provider.rs":"8aa8e41dfc64bb0adc24ed7f07a2687130bc59710cece2bd981a8b9e4e4a3594","src/rs.rs":"474fee04323c5c2881e679f57bea318c9ba2faa1873ce8f24abc4d92775dd7b4","src/schema.rs":"9e383221bdb11d84f4d1f2e7a7034983154917c92c5ed25b75fce5f5bf8fd159","src/store.rs":"7affafe7d9396821ff6bd19321837d1cb2e4ecc009880804e704d8cfcfca898f","src/suggest.udl":"d7a5ba8edf0f56affa8ac5be0b6111736840a56e1057cd7125c996da21e3d984","src/suggestion.rs":"053637820aaae3869005e5906bd29edb002f2e9b18172ee271e0c2aec35cd028","uniffi.toml":"fb8add80c2f660e4eacf95ec3f0b1d0f6a92ab5dbcf607782350442814ee26a7"},"package":null}
|
||||
4
third_party/rust/suggest/Cargo.toml
vendored
4
third_party/rust/suggest/Cargo.toml
vendored
|
|
@ -48,11 +48,15 @@ path = "../support/sql"
|
|||
|
||||
[dev-dependencies]
|
||||
expect-test = "1.4"
|
||||
hex = "0.4"
|
||||
|
||||
[dev-dependencies.env_logger]
|
||||
version = "0.7"
|
||||
default-features = false
|
||||
|
||||
[dev-dependencies.rc_crypto]
|
||||
path = "../support/rc_crypto"
|
||||
|
||||
[build-dependencies.uniffi]
|
||||
version = "0.24.1"
|
||||
features = ["build"]
|
||||
|
|
|
|||
165
third_party/rust/suggest/src/db.rs
vendored
165
third_party/rust/suggest/src/db.rs
vendored
|
|
@ -16,7 +16,8 @@ use sql_support::{open_database::open_database_with_flags, ConnExt};
|
|||
|
||||
use crate::{
|
||||
keyword::full_keyword,
|
||||
rs::{DownloadedSuggestion, SuggestRecordId},
|
||||
provider::SuggestionProvider,
|
||||
rs::{DownloadedAmpWikipediaSuggestion, SuggestRecordId},
|
||||
schema::SuggestConnectionInitializer,
|
||||
Result, Suggestion,
|
||||
};
|
||||
|
|
@ -25,10 +26,6 @@ use crate::{
|
|||
/// from the Suggest Remote Settings collection.
|
||||
pub const LAST_INGEST_META_KEY: &str = "last_quicksuggest_ingest";
|
||||
|
||||
/// A list of [`Suggestion::iab_category`] values used to distinguish
|
||||
/// non-sponsored suggestions.
|
||||
pub const NONSPONSORED_IAB_CATEGORIES: &[&str] = &["5 - Education"];
|
||||
|
||||
/// The database connection type.
|
||||
#[derive(Clone, Copy)]
|
||||
pub(crate) enum ConnectionType {
|
||||
|
|
@ -122,9 +119,7 @@ impl<'a> SuggestDao<'a> {
|
|||
/// Fetches suggestions that match the given keyword from the database.
|
||||
pub fn fetch_by_keyword(&self, keyword: &str) -> Result<Vec<Suggestion>> {
|
||||
self.conn.query_rows_and_then_cached(
|
||||
"SELECT s.id, k.rank, s.block_id, s.advertiser, s.iab_category,
|
||||
s.title, s.url, s.impression_url, s.click_url,
|
||||
(SELECT i.data FROM icons i WHERE i.id = s.icon_id) AS icon
|
||||
"SELECT s.id, k.rank, s.title, s.url, s.provider
|
||||
FROM suggestions s
|
||||
JOIN keywords k ON k.suggestion_id = s.id
|
||||
WHERE k.keyword = :keyword
|
||||
|
|
@ -133,82 +128,156 @@ impl<'a> SuggestDao<'a> {
|
|||
":keyword": keyword,
|
||||
},
|
||||
|row| -> Result<Suggestion>{
|
||||
let keywords: Vec<String> = self.conn.query_rows_and_then(
|
||||
let suggestion_id: i64 = row.get("id")?;
|
||||
let title = row.get("title")?;
|
||||
let url = row.get("url")?;
|
||||
let provider = row.get("provider")?;
|
||||
|
||||
let keywords: Vec<String> = self.conn.query_rows_and_then_cached(
|
||||
"SELECT keyword FROM keywords
|
||||
WHERE suggestion_id = :suggestion_id AND rank >= :rank
|
||||
ORDER BY rank ASC",
|
||||
named_params! {
|
||||
":suggestion_id": row.get::<_, i64>("id")?,
|
||||
":suggestion_id": suggestion_id,
|
||||
":rank": row.get::<_, i64>("rank")?,
|
||||
},
|
||||
|row| row.get(0),
|
||||
)?;
|
||||
let iab_category = row.get::<_, String>("iab_category")?;
|
||||
let is_sponsored = !NONSPONSORED_IAB_CATEGORIES.contains(&iab_category.as_str());
|
||||
Ok(Suggestion {
|
||||
|
||||
match provider {
|
||||
SuggestionProvider::Amp => {
|
||||
self.conn.query_row_and_then(
|
||||
"SELECT amp.advertiser, amp.block_id, amp.iab_category, amp.impression_url, amp.click_url,
|
||||
(SELECT i.data FROM icons i WHERE i.id = amp.icon_id) AS icon
|
||||
FROM amp_custom_details amp
|
||||
WHERE amp.suggestion_id = :suggestion_id",
|
||||
named_params! {
|
||||
":suggestion_id": suggestion_id
|
||||
},
|
||||
|row| {
|
||||
Ok(Suggestion::Amp {
|
||||
block_id: row.get("block_id")?,
|
||||
advertiser: row.get("advertiser")?,
|
||||
iab_category,
|
||||
is_sponsored,
|
||||
title: row.get("title")?,
|
||||
url: row.get("url")?,
|
||||
iab_category: row.get("iab_category")?,
|
||||
title,
|
||||
url,
|
||||
full_keyword: full_keyword(keyword, &keywords),
|
||||
icon: row.get("icon")?,
|
||||
impression_url: row.get("impression_url")?,
|
||||
click_url: row.get("click_url")?,
|
||||
})
|
||||
}
|
||||
)
|
||||
},
|
||||
SuggestionProvider::Wikipedia => {
|
||||
let icon = self.conn.try_query_one(
|
||||
"SELECT i.data
|
||||
FROM icons i
|
||||
JOIN wikipedia_custom_details s ON s.icon_id = i.id
|
||||
WHERE s.suggestion_id = :suggestion_id",
|
||||
named_params! {
|
||||
":suggestion_id": suggestion_id
|
||||
},
|
||||
true,
|
||||
)?;
|
||||
Ok(Suggestion::Wikipedia {
|
||||
title,
|
||||
url,
|
||||
full_keyword: full_keyword(keyword, &keywords),
|
||||
icon,
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/// Inserts all suggestions associated with a Remote Settings record into
|
||||
/// Inserts all suggestions from a downloaded AMP-Wikipedia attachment into
|
||||
/// the database.
|
||||
pub fn insert_suggestions(
|
||||
pub fn insert_amp_wikipedia_suggestions(
|
||||
&mut self,
|
||||
record_id: &SuggestRecordId,
|
||||
suggestions: &[DownloadedSuggestion],
|
||||
suggestions: &[DownloadedAmpWikipediaSuggestion],
|
||||
) -> Result<()> {
|
||||
for suggestion in suggestions {
|
||||
self.scope.err_if_interrupted()?;
|
||||
let common_details = suggestion.common_details();
|
||||
let provider = suggestion.provider();
|
||||
let suggestion_id: i64 = self.conn.query_row_and_then_cachable(
|
||||
"INSERT INTO suggestions(
|
||||
record_id,
|
||||
block_id,
|
||||
advertiser,
|
||||
iab_category,
|
||||
provider,
|
||||
title,
|
||||
url,
|
||||
icon_id,
|
||||
impression_url,
|
||||
click_url
|
||||
url
|
||||
)
|
||||
VALUES(
|
||||
:record_id,
|
||||
:block_id,
|
||||
:advertiser,
|
||||
:iab_category,
|
||||
:provider,
|
||||
:title,
|
||||
:url,
|
||||
:icon_id,
|
||||
:impression_url,
|
||||
:click_url
|
||||
:url
|
||||
)
|
||||
RETURNING id",
|
||||
RETURNING id
|
||||
",
|
||||
named_params! {
|
||||
":record_id": record_id.as_str(),
|
||||
":block_id": suggestion.block_id,
|
||||
":advertiser": suggestion.advertiser,
|
||||
":iab_category": suggestion.iab_category,
|
||||
":title": suggestion.title,
|
||||
":url": suggestion.url,
|
||||
":icon_id": suggestion.icon_id,
|
||||
":impression_url": suggestion.impression_url,
|
||||
":click_url": suggestion.click_url,
|
||||
":provider": &provider,
|
||||
":title": common_details.title,
|
||||
":url": common_details.url,
|
||||
|
||||
},
|
||||
|row| row.get(0),
|
||||
true,
|
||||
)?;
|
||||
for (index, keyword) in suggestion.keywords.iter().enumerate() {
|
||||
match suggestion {
|
||||
DownloadedAmpWikipediaSuggestion::Amp(amp) => {
|
||||
self.conn.execute(
|
||||
"INSERT INTO amp_custom_details(
|
||||
suggestion_id,
|
||||
advertiser,
|
||||
block_id,
|
||||
iab_category,
|
||||
impression_url,
|
||||
click_url,
|
||||
icon_id
|
||||
)
|
||||
VALUES(
|
||||
:suggestion_id,
|
||||
:advertiser,
|
||||
:block_id,
|
||||
:iab_category,
|
||||
:impression_url,
|
||||
:click_url,
|
||||
:icon_id
|
||||
)",
|
||||
named_params! {
|
||||
":suggestion_id": suggestion_id,
|
||||
":advertiser": amp.advertiser,
|
||||
":block_id": amp.block_id,
|
||||
":iab_category": amp.iab_category,
|
||||
":impression_url": amp.impression_url,
|
||||
":click_url": amp.click_url,
|
||||
":icon_id": amp.icon_id,
|
||||
},
|
||||
)?;
|
||||
}
|
||||
DownloadedAmpWikipediaSuggestion::Wikipedia(wikipedia) => {
|
||||
self.conn.execute(
|
||||
"INSERT INTO wikipedia_custom_details(
|
||||
suggestion_id,
|
||||
icon_id
|
||||
)
|
||||
VALUES(
|
||||
:suggestion_id,
|
||||
:icon_id
|
||||
)",
|
||||
named_params! {
|
||||
":suggestion_id": suggestion_id,
|
||||
":icon_id": wikipedia.icon_id,
|
||||
},
|
||||
)?;
|
||||
}
|
||||
}
|
||||
for (index, keyword) in common_details.keywords.iter().enumerate() {
|
||||
self.conn.execute(
|
||||
"INSERT INTO keywords(
|
||||
keyword,
|
||||
|
|
@ -231,10 +300,10 @@ impl<'a> SuggestDao<'a> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Inserts an icon for a suggestion into the database.
|
||||
pub fn insert_icon(&mut self, icon_id: &str, data: &[u8]) -> Result<()> {
|
||||
/// Inserts or replaces an icon for a suggestion into the database.
|
||||
pub fn put_icon(&mut self, icon_id: &str, data: &[u8]) -> Result<()> {
|
||||
self.conn.execute(
|
||||
"INSERT INTO icons(
|
||||
"INSERT OR REPLACE INTO icons(
|
||||
id,
|
||||
data
|
||||
)
|
||||
|
|
@ -291,7 +360,7 @@ impl<'a> SuggestDao<'a> {
|
|||
/// Sets the value for a metadata key.
|
||||
pub fn put_meta(&mut self, key: &str, value: impl ToSql) -> Result<()> {
|
||||
self.conn.execute_cached(
|
||||
"REPLACE INTO meta(key, value) VALUES(:key, :value)",
|
||||
"INSERT OR REPLACE INTO meta(key, value) VALUES(:key, :value)",
|
||||
named_params! { ":key": key, ":value": value },
|
||||
)?;
|
||||
Ok(())
|
||||
|
|
|
|||
20
third_party/rust/suggest/src/lib.rs
vendored
20
third_party/rust/suggest/src/lib.rs
vendored
|
|
@ -4,35 +4,23 @@
|
|||
*/
|
||||
|
||||
use remote_settings::RemoteSettingsConfig;
|
||||
|
||||
mod db;
|
||||
mod error;
|
||||
mod keyword;
|
||||
mod provider;
|
||||
mod rs;
|
||||
mod schema;
|
||||
mod store;
|
||||
mod suggestion;
|
||||
|
||||
pub use error::SuggestApiError;
|
||||
pub use provider::SuggestionProvider;
|
||||
pub use store::{SuggestIngestionConstraints, SuggestStore};
|
||||
pub use suggestion::Suggestion;
|
||||
|
||||
pub(crate) type Result<T> = std::result::Result<T, error::Error>;
|
||||
pub type SuggestApiResult<T> = std::result::Result<T, error::SuggestApiError>;
|
||||
|
||||
/// A suggestion from the database to show in the address bar.
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||
pub struct Suggestion {
|
||||
pub block_id: i64,
|
||||
pub advertiser: String,
|
||||
pub iab_category: String,
|
||||
pub is_sponsored: bool,
|
||||
pub full_keyword: String,
|
||||
pub title: String,
|
||||
pub url: String,
|
||||
pub icon: Option<Vec<u8>>,
|
||||
pub impression_url: Option<String>,
|
||||
pub click_url: Option<String>,
|
||||
}
|
||||
|
||||
/// A query for suggestions to show in the address bar.
|
||||
#[derive(Debug, Default)]
|
||||
pub struct SuggestionQuery {
|
||||
|
|
|
|||
44
third_party/rust/suggest/src/provider.rs
vendored
Normal file
44
third_party/rust/suggest/src/provider.rs
vendored
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
use rusqlite::{
|
||||
types::{FromSql, FromSqlError, FromSqlResult, ToSql, ToSqlOutput, ValueRef},
|
||||
Result as RusqliteResult,
|
||||
};
|
||||
|
||||
/// A provider is a source of search suggestions.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
|
||||
#[repr(u8)]
|
||||
pub enum SuggestionProvider {
|
||||
Amp = 1,
|
||||
Wikipedia = 2,
|
||||
}
|
||||
|
||||
impl FromSql for SuggestionProvider {
|
||||
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
|
||||
let v = value.as_i64()?;
|
||||
u8::try_from(v)
|
||||
.ok()
|
||||
.and_then(SuggestionProvider::from_u8)
|
||||
.ok_or_else(|| FromSqlError::OutOfRange(v))
|
||||
}
|
||||
}
|
||||
|
||||
impl SuggestionProvider {
|
||||
#[inline]
|
||||
pub(crate) fn from_u8(v: u8) -> Option<Self> {
|
||||
match v {
|
||||
1 => Some(SuggestionProvider::Amp),
|
||||
2 => Some(SuggestionProvider::Wikipedia),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSql for SuggestionProvider {
|
||||
fn to_sql(&self) -> RusqliteResult<ToSqlOutput<'_>> {
|
||||
Ok(ToSqlOutput::from(*self as u8))
|
||||
}
|
||||
}
|
||||
251
third_party/rust/suggest/src/rs.rs
vendored
251
third_party/rust/suggest/src/rs.rs
vendored
|
|
@ -1,9 +1,40 @@
|
|||
use std::ops::Deref;
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
use remote_settings::{Attachment, GetItemsOptions};
|
||||
use serde::Deserialize;
|
||||
//! Crate-internal types for interacting with Remote Settings (`rs`). Types in
|
||||
//! this module describe records and attachments in the Suggest Remote Settings
|
||||
//! collection.
|
||||
//!
|
||||
//! To add a new suggestion `T` to this component, you'll generally need to:
|
||||
//!
|
||||
//! 1. Add a variant named `T` to [`SuggestRecord`]. The variant must have a
|
||||
//! `#[serde(rename)]` attribute that matches the suggestion record's
|
||||
//! `type` field.
|
||||
//! 2. Define a `DownloadedTSuggestion` type with the new suggestion's fields,
|
||||
//! matching their attachment's schema. Your new type must derive or
|
||||
//! implement [`serde::Deserialize`].
|
||||
//! 3. Update the database schema in the [`schema`] module to store the new
|
||||
//! suggestion.
|
||||
//! 4. Add an `insert_t_suggestions()` method to [`db::SuggestDao`] that
|
||||
//! inserts `DownloadedTSuggestion`s into the database.
|
||||
//! 5. Update [`store::SuggestStoreInner::ingest()`] to download, deserialize,
|
||||
//! and store the new suggestion.
|
||||
//! 6. Add a variant named `T` to [`suggestion::Suggestion`], with the fields
|
||||
//! that you'd like to expose to the application. These can be the same
|
||||
//! fields as `DownloadedTSuggestion`, or slightly different, depending on
|
||||
//! what the application needs to show the suggestion.
|
||||
//! 7. Update any [`db::SuggestDao`] methods that query the database to include
|
||||
//! the new suggestion in their results, and return `Suggestion::T` variants
|
||||
//! as needed.
|
||||
|
||||
use crate::Result;
|
||||
use std::borrow::Cow;
|
||||
|
||||
use remote_settings::{GetItemsOptions, RemoteSettingsResponse};
|
||||
use serde::{Deserialize, Deserializer};
|
||||
|
||||
use crate::{provider::SuggestionProvider, Result};
|
||||
|
||||
/// The Suggest Remote Settings collection name.
|
||||
pub(crate) const REMOTE_SETTINGS_COLLECTION: &str = "quicksuggest";
|
||||
|
|
@ -19,119 +50,72 @@ pub(crate) const SUGGESTIONS_PER_ATTACHMENT: u64 = 200;
|
|||
/// This trait lets tests use a mock client.
|
||||
pub(crate) trait SuggestRemoteSettingsClient {
|
||||
/// Fetches records from the Suggest Remote Settings collection.
|
||||
fn get_records_with_options(
|
||||
&self,
|
||||
options: &GetItemsOptions,
|
||||
) -> Result<SuggestRemoteSettingsRecords>;
|
||||
fn get_records_with_options(&self, options: &GetItemsOptions)
|
||||
-> Result<RemoteSettingsResponse>;
|
||||
|
||||
/// Fetches a data attachment with suggestions to ingest from the Suggest
|
||||
/// Remote Settings collection.
|
||||
fn get_data_attachment(&self, location: &str) -> Result<DownloadedSuggestDataAttachment>;
|
||||
|
||||
/// Fetches an icon attachment from the Suggest Remote Settings collection.
|
||||
fn get_icon_attachment(&self, location: &str) -> Result<Vec<u8>>;
|
||||
/// Fetches a record's attachment from the Suggest Remote Settings
|
||||
/// collection.
|
||||
fn get_attachment(&self, location: &str) -> Result<Vec<u8>>;
|
||||
}
|
||||
|
||||
impl SuggestRemoteSettingsClient for remote_settings::Client {
|
||||
fn get_records_with_options(
|
||||
&self,
|
||||
options: &GetItemsOptions,
|
||||
) -> Result<SuggestRemoteSettingsRecords> {
|
||||
Ok(self.get_records_raw_with_options(options)?.json()?)
|
||||
) -> Result<RemoteSettingsResponse> {
|
||||
Ok(remote_settings::Client::get_records_with_options(
|
||||
self, options,
|
||||
)?)
|
||||
}
|
||||
|
||||
fn get_data_attachment(&self, location: &str) -> Result<DownloadedSuggestDataAttachment> {
|
||||
Ok(self.get_attachment(location)?.json()?)
|
||||
}
|
||||
|
||||
fn get_icon_attachment(&self, location: &str) -> Result<Vec<u8>> {
|
||||
Ok(self.get_attachment(location)?.body)
|
||||
fn get_attachment(&self, location: &str) -> Result<Vec<u8>> {
|
||||
Ok(remote_settings::Client::get_attachment(self, location)?)
|
||||
}
|
||||
}
|
||||
|
||||
/// The response body for a Suggest Remote Settings collection request.
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
pub(crate) struct SuggestRemoteSettingsRecords {
|
||||
pub data: Vec<SuggestRecord>,
|
||||
}
|
||||
|
||||
/// A record with a known or an unknown type, or a tombstone, in the Suggest
|
||||
/// Remote Settings collection.
|
||||
/// A record in the Suggest Remote Settings collection.
|
||||
///
|
||||
/// Because `#[serde(other)]` doesn't support associated data
|
||||
/// (serde-rs/serde#1973), we can't define variants for all the known types and
|
||||
/// the unknown type in the same enum. Instead, we have this "outer", untagged
|
||||
/// `SuggestRecord` with the "unknown type" variant, and an "inner", internally
|
||||
/// tagged `TypedSuggestRecord` with all the "known type" variants.
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq)]
|
||||
#[serde(untagged)]
|
||||
pub(crate) enum SuggestRecord {
|
||||
/// A record with a known type.
|
||||
Typed(TypedSuggestRecord),
|
||||
|
||||
/// A tombstone, or a record with an unknown type, that we don't know how
|
||||
/// to ingest.
|
||||
///
|
||||
/// Tombstones only have these three fields, with `deleted` set to `true`.
|
||||
/// Records with unknown types have `deleted` set to `false`, and may
|
||||
/// contain other fields that we ignore.
|
||||
Untyped {
|
||||
id: SuggestRecordId,
|
||||
last_modified: u64,
|
||||
#[serde(default)]
|
||||
deleted: bool,
|
||||
},
|
||||
}
|
||||
|
||||
/// A record that we know how to ingest from Remote Settings.
|
||||
/// Except for the type, Suggest records don't carry additional fields. All
|
||||
/// suggestions are stored in each record's attachment.
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq)]
|
||||
#[serde(tag = "type")]
|
||||
pub(crate) enum TypedSuggestRecord {
|
||||
pub(crate) enum SuggestRecord {
|
||||
#[serde(rename = "icon")]
|
||||
Icon {
|
||||
id: SuggestRecordId,
|
||||
last_modified: u64,
|
||||
attachment: Attachment,
|
||||
},
|
||||
Icon,
|
||||
#[serde(rename = "data")]
|
||||
Data {
|
||||
id: SuggestRecordId,
|
||||
last_modified: u64,
|
||||
attachment: Attachment,
|
||||
},
|
||||
AmpWikipedia,
|
||||
}
|
||||
|
||||
/// Represents either a single value, or a list of values. This is used to
|
||||
/// deserialize downloaded data attachments.
|
||||
/// deserialize downloaded attachments.
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub(crate) enum OneOrMany<T> {
|
||||
enum OneOrMany<T> {
|
||||
One(T),
|
||||
Many(Vec<T>),
|
||||
}
|
||||
|
||||
impl<T> Deref for OneOrMany<T> {
|
||||
type Target = [T];
|
||||
/// A downloaded Remote Settings attachment that contains suggestions.
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(transparent)]
|
||||
pub(crate) struct SuggestAttachment<T>(OneOrMany<T>);
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
match self {
|
||||
impl<T> SuggestAttachment<T> {
|
||||
/// Returns a slice of suggestions to ingest from the downloaded attachment.
|
||||
pub fn suggestions(&self) -> &[T] {
|
||||
match &self.0 {
|
||||
OneOrMany::One(value) => std::slice::from_ref(value),
|
||||
OneOrMany::Many(values) => values,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The contents of a downloaded [`TypedSuggestRecord::Data`] attachment.
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(transparent)]
|
||||
pub(crate) struct DownloadedSuggestDataAttachment(pub OneOrMany<DownloadedSuggestion>);
|
||||
|
||||
/// The ID of a record in the Suggest Remote Settings collection.
|
||||
#[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
||||
#[serde(transparent)]
|
||||
pub(crate) struct SuggestRecordId(String);
|
||||
pub(crate) struct SuggestRecordId<'a>(Cow<'a, str>);
|
||||
|
||||
impl SuggestRecordId {
|
||||
impl<'a> SuggestRecordId<'a> {
|
||||
pub fn as_str(&self) -> &str {
|
||||
&self.0
|
||||
}
|
||||
|
|
@ -146,18 +130,107 @@ impl SuggestRecordId {
|
|||
}
|
||||
}
|
||||
|
||||
/// A suggestion to ingest from a downloaded Remote Settings attachment.
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
pub(crate) struct DownloadedSuggestion {
|
||||
#[serde(rename = "id")]
|
||||
pub block_id: i64,
|
||||
pub advertiser: String,
|
||||
pub iab_category: String,
|
||||
impl<'a, T> From<T> for SuggestRecordId<'a>
|
||||
where
|
||||
T: Into<Cow<'a, str>>,
|
||||
{
|
||||
fn from(value: T) -> Self {
|
||||
Self(value.into())
|
||||
}
|
||||
}
|
||||
|
||||
/// Fields that are common to all downloaded suggestions.
|
||||
#[derive(Clone, Debug, Deserialize, Eq, PartialEq)]
|
||||
pub(crate) struct DownloadedSuggestionCommonDetails {
|
||||
pub keywords: Vec<String>,
|
||||
pub title: String,
|
||||
pub url: String,
|
||||
}
|
||||
|
||||
/// An AMP suggestion to ingest from an AMP-Wikipedia attachment.
|
||||
#[derive(Clone, Debug, Deserialize, Eq, PartialEq)]
|
||||
pub(crate) struct DownloadedAmpSuggestion {
|
||||
#[serde(flatten)]
|
||||
pub common_details: DownloadedSuggestionCommonDetails,
|
||||
pub advertiser: String,
|
||||
#[serde(rename = "id")]
|
||||
pub block_id: i32,
|
||||
pub iab_category: String,
|
||||
pub click_url: String,
|
||||
pub impression_url: String,
|
||||
#[serde(rename = "icon")]
|
||||
pub icon_id: String,
|
||||
pub impression_url: Option<String>,
|
||||
pub click_url: Option<String>,
|
||||
}
|
||||
|
||||
/// A Wikipedia suggestion to ingest from an AMP-Wikipedia attachment.
|
||||
#[derive(Clone, Debug, Deserialize, Eq, PartialEq)]
|
||||
pub(crate) struct DownloadedWikipediaSuggestion {
|
||||
#[serde(flatten)]
|
||||
pub common_details: DownloadedSuggestionCommonDetails,
|
||||
#[serde(rename = "icon")]
|
||||
pub icon_id: String,
|
||||
}
|
||||
|
||||
/// A suggestion to ingest from an AMP-Wikipedia attachment downloaded from
|
||||
/// Remote Settings.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub(crate) enum DownloadedAmpWikipediaSuggestion {
|
||||
Amp(DownloadedAmpSuggestion),
|
||||
Wikipedia(DownloadedWikipediaSuggestion),
|
||||
}
|
||||
|
||||
impl DownloadedAmpWikipediaSuggestion {
|
||||
/// Returns the details that are common to AMP and Wikipedia suggestions.
|
||||
pub fn common_details(&self) -> &DownloadedSuggestionCommonDetails {
|
||||
match self {
|
||||
Self::Amp(DownloadedAmpSuggestion { common_details, .. }) => common_details,
|
||||
Self::Wikipedia(DownloadedWikipediaSuggestion { common_details, .. }) => common_details,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the provider of this suggestion.
|
||||
pub fn provider(&self) -> SuggestionProvider {
|
||||
match self {
|
||||
DownloadedAmpWikipediaSuggestion::Amp(_) => SuggestionProvider::Amp,
|
||||
DownloadedAmpWikipediaSuggestion::Wikipedia(_) => SuggestionProvider::Wikipedia,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for DownloadedAmpWikipediaSuggestion {
|
||||
fn deserialize<D>(
|
||||
deserializer: D,
|
||||
) -> std::result::Result<DownloadedAmpWikipediaSuggestion, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
// AMP and Wikipedia suggestions use the same schema. To separate them,
|
||||
// we use a "maybe tagged" outer enum with tagged and untagged variants,
|
||||
// and a "tagged" inner enum.
|
||||
//
|
||||
// Wikipedia suggestions will deserialize successfully into the tagged
|
||||
// variant. AMP suggestions will try the tagged variant, fail, and fall
|
||||
// back to the untagged variant.
|
||||
//
|
||||
// This approach works around serde-rs/serde#912.
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(untagged)]
|
||||
enum MaybeTagged {
|
||||
Tagged(Tagged),
|
||||
Untagged(DownloadedAmpSuggestion),
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(tag = "advertiser")]
|
||||
enum Tagged {
|
||||
#[serde(rename = "Wikipedia")]
|
||||
Wikipedia(DownloadedWikipediaSuggestion),
|
||||
}
|
||||
|
||||
Ok(match MaybeTagged::deserialize(deserializer)? {
|
||||
MaybeTagged::Tagged(Tagged::Wikipedia(wikipedia)) => Self::Wikipedia(wikipedia),
|
||||
MaybeTagged::Untagged(amp) => Self::Amp(amp),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
36
third_party/rust/suggest/src/schema.rs
vendored
36
third_party/rust/suggest/src/schema.rs
vendored
|
|
@ -6,7 +6,7 @@
|
|||
use rusqlite::{Connection, Transaction};
|
||||
use sql_support::open_database::{self, ConnectionInitializer};
|
||||
|
||||
pub const VERSION: u32 = 1;
|
||||
pub const VERSION: u32 = 3;
|
||||
|
||||
pub const SQL: &str = "
|
||||
CREATE TABLE meta(
|
||||
|
|
@ -26,14 +26,26 @@ pub const SQL: &str = "
|
|||
CREATE TABLE suggestions(
|
||||
id INTEGER PRIMARY KEY,
|
||||
record_id TEXT NOT NULL,
|
||||
block_id INTEGER NOT NULL,
|
||||
advertiser TEXT NOT NULL,
|
||||
iab_category TEXT NOT NULL,
|
||||
provider INTEGER NOT NULL,
|
||||
title TEXT NOT NULL,
|
||||
url TEXT NOT NULL,
|
||||
url TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE amp_custom_details(
|
||||
suggestion_id INTEGER PRIMARY KEY,
|
||||
advertiser TEXT NOT NULL,
|
||||
block_id INTEGER NOT NULL,
|
||||
iab_category TEXT NOT NULL,
|
||||
impression_url TEXT NOT NULL,
|
||||
click_url TEXT NOT NULL,
|
||||
icon_id TEXT NOT NULL,
|
||||
impression_url TEXT,
|
||||
click_url TEXT
|
||||
FOREIGN KEY(suggestion_id) REFERENCES suggestions(id)
|
||||
ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE wikipedia_custom_details(
|
||||
suggestion_id INTEGER PRIMARY KEY REFERENCES suggestions(id) ON DELETE CASCADE,
|
||||
icon_id TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX suggestions_record_id ON suggestions(record_id);
|
||||
|
|
@ -71,6 +83,14 @@ impl ConnectionInitializer for SuggestConnectionInitializer {
|
|||
}
|
||||
|
||||
fn upgrade_from(&self, _db: &Transaction<'_>, version: u32) -> open_database::Result<()> {
|
||||
Err(open_database::Error::IncompatibleVersion(version))
|
||||
match version {
|
||||
1..=2 => {
|
||||
// These schema versions were used during development, and never
|
||||
// shipped in any applications. Treat these databases as
|
||||
// corrupt, so that they'll be replaced.
|
||||
Err(open_database::Error::Corrupt)
|
||||
}
|
||||
_ => Err(open_database::Error::IncompatibleVersion(version)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
725
third_party/rust/suggest/src/store.rs
vendored
725
third_party/rust/suggest/src/store.rs
vendored
File diff suppressed because it is too large
Load diff
36
third_party/rust/suggest/src/suggest.udl
vendored
36
third_party/rust/suggest/src/suggest.udl
vendored
|
|
@ -15,17 +15,31 @@ interface SuggestApiError {
|
|||
Other(string reason);
|
||||
};
|
||||
|
||||
dictionary Suggestion {
|
||||
i64 block_id;
|
||||
string advertiser;
|
||||
string iab_category;
|
||||
boolean is_sponsored;
|
||||
string full_keyword;
|
||||
string title;
|
||||
string url;
|
||||
sequence<u8>? icon;
|
||||
string? impression_url;
|
||||
string? click_url;
|
||||
|
||||
enum SuggestionProvider {
|
||||
"Amp",
|
||||
"Wikipedia",
|
||||
};
|
||||
|
||||
[Enum]
|
||||
interface Suggestion {
|
||||
Amp(
|
||||
string title,
|
||||
string url,
|
||||
sequence<u8>? icon,
|
||||
string full_keyword,
|
||||
i64 block_id,
|
||||
string advertiser,
|
||||
string iab_category,
|
||||
string impression_url,
|
||||
string click_url
|
||||
);
|
||||
Wikipedia(
|
||||
string title,
|
||||
string url,
|
||||
sequence<u8>? icon,
|
||||
string full_keyword
|
||||
);
|
||||
};
|
||||
|
||||
dictionary SuggestionQuery {
|
||||
|
|
|
|||
33
third_party/rust/suggest/src/suggestion.rs
vendored
Normal file
33
third_party/rust/suggest/src/suggestion.rs
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
/// A suggestion from the database to show in the address bar.
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||
pub enum Suggestion {
|
||||
Amp {
|
||||
title: String,
|
||||
url: String,
|
||||
icon: Option<Vec<u8>>,
|
||||
full_keyword: String,
|
||||
block_id: i64,
|
||||
advertiser: String,
|
||||
iab_category: String,
|
||||
impression_url: String,
|
||||
click_url: String,
|
||||
},
|
||||
Wikipedia {
|
||||
title: String,
|
||||
url: String,
|
||||
icon: Option<Vec<u8>>,
|
||||
full_keyword: String,
|
||||
},
|
||||
}
|
||||
|
||||
impl Suggestion {
|
||||
/// Returns `true` if the suggestion is sponsored.
|
||||
pub(crate) fn is_sponsored(&self) -> bool {
|
||||
matches!(self, Self::Amp { .. })
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -578,244 +578,6 @@ export class FfiConverterTypeSuggestIngestionConstraints extends FfiConverterArr
|
|||
}
|
||||
}
|
||||
|
||||
export class Suggestion {
|
||||
constructor(blockId,advertiser,iabCategory,isSponsored,fullKeyword,title,url,icon,impressionUrl,clickUrl) {
|
||||
try {
|
||||
FfiConverterI64.checkType(blockId)
|
||||
} catch (e) {
|
||||
if (e instanceof UniFFITypeError) {
|
||||
e.addItemDescriptionPart("blockId");
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
try {
|
||||
FfiConverterString.checkType(advertiser)
|
||||
} catch (e) {
|
||||
if (e instanceof UniFFITypeError) {
|
||||
e.addItemDescriptionPart("advertiser");
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
try {
|
||||
FfiConverterString.checkType(iabCategory)
|
||||
} catch (e) {
|
||||
if (e instanceof UniFFITypeError) {
|
||||
e.addItemDescriptionPart("iabCategory");
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
try {
|
||||
FfiConverterBool.checkType(isSponsored)
|
||||
} catch (e) {
|
||||
if (e instanceof UniFFITypeError) {
|
||||
e.addItemDescriptionPart("isSponsored");
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
try {
|
||||
FfiConverterString.checkType(fullKeyword)
|
||||
} catch (e) {
|
||||
if (e instanceof UniFFITypeError) {
|
||||
e.addItemDescriptionPart("fullKeyword");
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
try {
|
||||
FfiConverterString.checkType(title)
|
||||
} catch (e) {
|
||||
if (e instanceof UniFFITypeError) {
|
||||
e.addItemDescriptionPart("title");
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
try {
|
||||
FfiConverterString.checkType(url)
|
||||
} catch (e) {
|
||||
if (e instanceof UniFFITypeError) {
|
||||
e.addItemDescriptionPart("url");
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
try {
|
||||
FfiConverterOptionalSequenceu8.checkType(icon)
|
||||
} catch (e) {
|
||||
if (e instanceof UniFFITypeError) {
|
||||
e.addItemDescriptionPart("icon");
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
try {
|
||||
FfiConverterOptionalstring.checkType(impressionUrl)
|
||||
} catch (e) {
|
||||
if (e instanceof UniFFITypeError) {
|
||||
e.addItemDescriptionPart("impressionUrl");
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
try {
|
||||
FfiConverterOptionalstring.checkType(clickUrl)
|
||||
} catch (e) {
|
||||
if (e instanceof UniFFITypeError) {
|
||||
e.addItemDescriptionPart("clickUrl");
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
this.blockId = blockId;
|
||||
this.advertiser = advertiser;
|
||||
this.iabCategory = iabCategory;
|
||||
this.isSponsored = isSponsored;
|
||||
this.fullKeyword = fullKeyword;
|
||||
this.title = title;
|
||||
this.url = url;
|
||||
this.icon = icon;
|
||||
this.impressionUrl = impressionUrl;
|
||||
this.clickUrl = clickUrl;
|
||||
}
|
||||
equals(other) {
|
||||
return (
|
||||
this.blockId == other.blockId &&
|
||||
this.advertiser == other.advertiser &&
|
||||
this.iabCategory == other.iabCategory &&
|
||||
this.isSponsored == other.isSponsored &&
|
||||
this.fullKeyword == other.fullKeyword &&
|
||||
this.title == other.title &&
|
||||
this.url == other.url &&
|
||||
this.icon == other.icon &&
|
||||
this.impressionUrl == other.impressionUrl &&
|
||||
this.clickUrl == other.clickUrl
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Export the FFIConverter object to make external types work.
|
||||
export class FfiConverterTypeSuggestion extends FfiConverterArrayBuffer {
|
||||
static read(dataStream) {
|
||||
return new Suggestion(
|
||||
FfiConverterI64.read(dataStream),
|
||||
FfiConverterString.read(dataStream),
|
||||
FfiConverterString.read(dataStream),
|
||||
FfiConverterBool.read(dataStream),
|
||||
FfiConverterString.read(dataStream),
|
||||
FfiConverterString.read(dataStream),
|
||||
FfiConverterString.read(dataStream),
|
||||
FfiConverterOptionalSequenceu8.read(dataStream),
|
||||
FfiConverterOptionalstring.read(dataStream),
|
||||
FfiConverterOptionalstring.read(dataStream)
|
||||
);
|
||||
}
|
||||
static write(dataStream, value) {
|
||||
FfiConverterI64.write(dataStream, value.blockId);
|
||||
FfiConverterString.write(dataStream, value.advertiser);
|
||||
FfiConverterString.write(dataStream, value.iabCategory);
|
||||
FfiConverterBool.write(dataStream, value.isSponsored);
|
||||
FfiConverterString.write(dataStream, value.fullKeyword);
|
||||
FfiConverterString.write(dataStream, value.title);
|
||||
FfiConverterString.write(dataStream, value.url);
|
||||
FfiConverterOptionalSequenceu8.write(dataStream, value.icon);
|
||||
FfiConverterOptionalstring.write(dataStream, value.impressionUrl);
|
||||
FfiConverterOptionalstring.write(dataStream, value.clickUrl);
|
||||
}
|
||||
|
||||
static computeSize(value) {
|
||||
let totalSize = 0;
|
||||
totalSize += FfiConverterI64.computeSize(value.blockId);
|
||||
totalSize += FfiConverterString.computeSize(value.advertiser);
|
||||
totalSize += FfiConverterString.computeSize(value.iabCategory);
|
||||
totalSize += FfiConverterBool.computeSize(value.isSponsored);
|
||||
totalSize += FfiConverterString.computeSize(value.fullKeyword);
|
||||
totalSize += FfiConverterString.computeSize(value.title);
|
||||
totalSize += FfiConverterString.computeSize(value.url);
|
||||
totalSize += FfiConverterOptionalSequenceu8.computeSize(value.icon);
|
||||
totalSize += FfiConverterOptionalstring.computeSize(value.impressionUrl);
|
||||
totalSize += FfiConverterOptionalstring.computeSize(value.clickUrl);
|
||||
return totalSize
|
||||
}
|
||||
|
||||
static checkType(value) {
|
||||
super.checkType(value);
|
||||
try {
|
||||
FfiConverterI64.checkType(value.blockId);
|
||||
} catch (e) {
|
||||
if (e instanceof UniFFITypeError) {
|
||||
e.addItemDescriptionPart(".blockId");
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
try {
|
||||
FfiConverterString.checkType(value.advertiser);
|
||||
} catch (e) {
|
||||
if (e instanceof UniFFITypeError) {
|
||||
e.addItemDescriptionPart(".advertiser");
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
try {
|
||||
FfiConverterString.checkType(value.iabCategory);
|
||||
} catch (e) {
|
||||
if (e instanceof UniFFITypeError) {
|
||||
e.addItemDescriptionPart(".iabCategory");
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
try {
|
||||
FfiConverterBool.checkType(value.isSponsored);
|
||||
} catch (e) {
|
||||
if (e instanceof UniFFITypeError) {
|
||||
e.addItemDescriptionPart(".isSponsored");
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
try {
|
||||
FfiConverterString.checkType(value.fullKeyword);
|
||||
} catch (e) {
|
||||
if (e instanceof UniFFITypeError) {
|
||||
e.addItemDescriptionPart(".fullKeyword");
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
try {
|
||||
FfiConverterString.checkType(value.title);
|
||||
} catch (e) {
|
||||
if (e instanceof UniFFITypeError) {
|
||||
e.addItemDescriptionPart(".title");
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
try {
|
||||
FfiConverterString.checkType(value.url);
|
||||
} catch (e) {
|
||||
if (e instanceof UniFFITypeError) {
|
||||
e.addItemDescriptionPart(".url");
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
try {
|
||||
FfiConverterOptionalSequenceu8.checkType(value.icon);
|
||||
} catch (e) {
|
||||
if (e instanceof UniFFITypeError) {
|
||||
e.addItemDescriptionPart(".icon");
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
try {
|
||||
FfiConverterOptionalstring.checkType(value.impressionUrl);
|
||||
} catch (e) {
|
||||
if (e instanceof UniFFITypeError) {
|
||||
e.addItemDescriptionPart(".impressionUrl");
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
try {
|
||||
FfiConverterOptionalstring.checkType(value.clickUrl);
|
||||
} catch (e) {
|
||||
if (e instanceof UniFFITypeError) {
|
||||
e.addItemDescriptionPart(".clickUrl");
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class SuggestionQuery {
|
||||
constructor(keyword,includeSponsored,includeNonSponsored) {
|
||||
try {
|
||||
|
|
@ -960,6 +722,177 @@ export class FfiConverterTypeSuggestApiError extends FfiConverterArrayBuffer {
|
|||
static errorClass = SuggestApiError;
|
||||
}
|
||||
|
||||
|
||||
export class Suggestion {}
|
||||
Suggestion.Amp = class extends Suggestion{
|
||||
constructor(
|
||||
title,
|
||||
url,
|
||||
icon,
|
||||
fullKeyword,
|
||||
blockId,
|
||||
advertiser,
|
||||
iabCategory,
|
||||
impressionUrl,
|
||||
clickUrl
|
||||
) {
|
||||
super();
|
||||
this.title = title;
|
||||
this.url = url;
|
||||
this.icon = icon;
|
||||
this.fullKeyword = fullKeyword;
|
||||
this.blockId = blockId;
|
||||
this.advertiser = advertiser;
|
||||
this.iabCategory = iabCategory;
|
||||
this.impressionUrl = impressionUrl;
|
||||
this.clickUrl = clickUrl;
|
||||
}
|
||||
}
|
||||
Suggestion.Wikipedia = class extends Suggestion{
|
||||
constructor(
|
||||
title,
|
||||
url,
|
||||
icon,
|
||||
fullKeyword
|
||||
) {
|
||||
super();
|
||||
this.title = title;
|
||||
this.url = url;
|
||||
this.icon = icon;
|
||||
this.fullKeyword = fullKeyword;
|
||||
}
|
||||
}
|
||||
|
||||
// Export the FFIConverter object to make external types work.
|
||||
export class FfiConverterTypeSuggestion extends FfiConverterArrayBuffer {
|
||||
static read(dataStream) {
|
||||
switch (dataStream.readInt32()) {
|
||||
case 1:
|
||||
return new Suggestion.Amp(
|
||||
FfiConverterString.read(dataStream),
|
||||
FfiConverterString.read(dataStream),
|
||||
FfiConverterOptionalSequenceu8.read(dataStream),
|
||||
FfiConverterString.read(dataStream),
|
||||
FfiConverterI64.read(dataStream),
|
||||
FfiConverterString.read(dataStream),
|
||||
FfiConverterString.read(dataStream),
|
||||
FfiConverterString.read(dataStream),
|
||||
FfiConverterString.read(dataStream)
|
||||
);
|
||||
case 2:
|
||||
return new Suggestion.Wikipedia(
|
||||
FfiConverterString.read(dataStream),
|
||||
FfiConverterString.read(dataStream),
|
||||
FfiConverterOptionalSequenceu8.read(dataStream),
|
||||
FfiConverterString.read(dataStream)
|
||||
);
|
||||
default:
|
||||
return new Error("Unknown Suggestion variant");
|
||||
}
|
||||
}
|
||||
|
||||
static write(dataStream, value) {
|
||||
if (value instanceof Suggestion.Amp) {
|
||||
dataStream.writeInt32(1);
|
||||
FfiConverterString.write(dataStream, value.title);
|
||||
FfiConverterString.write(dataStream, value.url);
|
||||
FfiConverterOptionalSequenceu8.write(dataStream, value.icon);
|
||||
FfiConverterString.write(dataStream, value.fullKeyword);
|
||||
FfiConverterI64.write(dataStream, value.blockId);
|
||||
FfiConverterString.write(dataStream, value.advertiser);
|
||||
FfiConverterString.write(dataStream, value.iabCategory);
|
||||
FfiConverterString.write(dataStream, value.impressionUrl);
|
||||
FfiConverterString.write(dataStream, value.clickUrl);
|
||||
return;
|
||||
}
|
||||
if (value instanceof Suggestion.Wikipedia) {
|
||||
dataStream.writeInt32(2);
|
||||
FfiConverterString.write(dataStream, value.title);
|
||||
FfiConverterString.write(dataStream, value.url);
|
||||
FfiConverterOptionalSequenceu8.write(dataStream, value.icon);
|
||||
FfiConverterString.write(dataStream, value.fullKeyword);
|
||||
return;
|
||||
}
|
||||
return new Error("Unknown Suggestion variant");
|
||||
}
|
||||
|
||||
static computeSize(value) {
|
||||
// Size of the Int indicating the variant
|
||||
let totalSize = 4;
|
||||
if (value instanceof Suggestion.Amp) {
|
||||
totalSize += FfiConverterString.computeSize(value.title);
|
||||
totalSize += FfiConverterString.computeSize(value.url);
|
||||
totalSize += FfiConverterOptionalSequenceu8.computeSize(value.icon);
|
||||
totalSize += FfiConverterString.computeSize(value.fullKeyword);
|
||||
totalSize += FfiConverterI64.computeSize(value.blockId);
|
||||
totalSize += FfiConverterString.computeSize(value.advertiser);
|
||||
totalSize += FfiConverterString.computeSize(value.iabCategory);
|
||||
totalSize += FfiConverterString.computeSize(value.impressionUrl);
|
||||
totalSize += FfiConverterString.computeSize(value.clickUrl);
|
||||
return totalSize;
|
||||
}
|
||||
if (value instanceof Suggestion.Wikipedia) {
|
||||
totalSize += FfiConverterString.computeSize(value.title);
|
||||
totalSize += FfiConverterString.computeSize(value.url);
|
||||
totalSize += FfiConverterOptionalSequenceu8.computeSize(value.icon);
|
||||
totalSize += FfiConverterString.computeSize(value.fullKeyword);
|
||||
return totalSize;
|
||||
}
|
||||
return new Error("Unknown Suggestion variant");
|
||||
}
|
||||
|
||||
static checkType(value) {
|
||||
if (!(value instanceof Suggestion)) {
|
||||
throw new UniFFITypeError(`${value} is not a subclass instance of Suggestion`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
export const SuggestionProvider = {
|
||||
AMP: 1,
|
||||
WIKIPEDIA: 2,
|
||||
};
|
||||
|
||||
Object.freeze(SuggestionProvider);
|
||||
// Export the FFIConverter object to make external types work.
|
||||
export class FfiConverterTypeSuggestionProvider extends FfiConverterArrayBuffer {
|
||||
static read(dataStream) {
|
||||
switch (dataStream.readInt32()) {
|
||||
case 1:
|
||||
return SuggestionProvider.AMP
|
||||
case 2:
|
||||
return SuggestionProvider.WIKIPEDIA
|
||||
default:
|
||||
return new Error("Unknown SuggestionProvider variant");
|
||||
}
|
||||
}
|
||||
|
||||
static write(dataStream, value) {
|
||||
if (value === SuggestionProvider.AMP) {
|
||||
dataStream.writeInt32(1);
|
||||
return;
|
||||
}
|
||||
if (value === SuggestionProvider.WIKIPEDIA) {
|
||||
dataStream.writeInt32(2);
|
||||
return;
|
||||
}
|
||||
return new Error("Unknown SuggestionProvider variant");
|
||||
}
|
||||
|
||||
static computeSize(value) {
|
||||
return 4;
|
||||
}
|
||||
|
||||
static checkType(value) {
|
||||
if (!Number.isInteger(value) || value < 1 || value > 2) {
|
||||
throw new UniFFITypeError(`${value} is not a valid value for SuggestionProvider`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Export the FFIConverter object to make external types work.
|
||||
export class FfiConverterOptionalu64 extends FfiConverterArrayBuffer {
|
||||
static checkType(value) {
|
||||
|
|
@ -997,43 +930,6 @@ export class FfiConverterOptionalu64 extends FfiConverterArrayBuffer {
|
|||
}
|
||||
}
|
||||
|
||||
// Export the FFIConverter object to make external types work.
|
||||
export class FfiConverterOptionalstring extends FfiConverterArrayBuffer {
|
||||
static checkType(value) {
|
||||
if (value !== undefined && value !== null) {
|
||||
FfiConverterString.checkType(value)
|
||||
}
|
||||
}
|
||||
|
||||
static read(dataStream) {
|
||||
const code = dataStream.readUint8(0);
|
||||
switch (code) {
|
||||
case 0:
|
||||
return null
|
||||
case 1:
|
||||
return FfiConverterString.read(dataStream)
|
||||
default:
|
||||
throw UniFFIError(`Unexpected code: ${code}`);
|
||||
}
|
||||
}
|
||||
|
||||
static write(dataStream, value) {
|
||||
if (value === null || value === undefined) {
|
||||
dataStream.writeUint8(0);
|
||||
return;
|
||||
}
|
||||
dataStream.writeUint8(1);
|
||||
FfiConverterString.write(dataStream, value)
|
||||
}
|
||||
|
||||
static computeSize(value) {
|
||||
if (value === null || value === undefined) {
|
||||
return 1;
|
||||
}
|
||||
return 1 + FfiConverterString.computeSize(value)
|
||||
}
|
||||
}
|
||||
|
||||
// Export the FFIConverter object to make external types work.
|
||||
export class FfiConverterOptionalSequenceu8 extends FfiConverterArrayBuffer {
|
||||
static checkType(value) {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
EXTRA_JS_MODULES += [
|
||||
"generated/RustRemoteSettings.sys.mjs",
|
||||
"generated/RustSuggest.sys.mjs",
|
||||
"generated/RustSync15.sys.mjs",
|
||||
"generated/RustTabs.sys.mjs",
|
||||
|
|
|
|||
|
|
@ -4,6 +4,12 @@ main = [
|
|||
"log_even_numbers_main_thread",
|
||||
]
|
||||
|
||||
[remote_settings.receiver_thread]
|
||||
default = "worker"
|
||||
main = [
|
||||
"RemoteSettings",
|
||||
]
|
||||
|
||||
[suggest.receiver_thread]
|
||||
default = "worker"
|
||||
main = [
|
||||
|
|
|
|||
|
|
@ -377,7 +377,7 @@ export function add(a,b) {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
25, // arithmetic:uniffi_arithmetic_fn_func_add
|
||||
29, // arithmetic:uniffi_arithmetic_fn_func_add
|
||||
FfiConverterU64.lower(a),
|
||||
FfiConverterU64.lower(b),
|
||||
)
|
||||
|
|
@ -411,7 +411,7 @@ export function sub(a,b) {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
26, // arithmetic:uniffi_arithmetic_fn_func_sub
|
||||
30, // arithmetic:uniffi_arithmetic_fn_func_sub
|
||||
FfiConverterU64.lower(a),
|
||||
FfiConverterU64.lower(b),
|
||||
)
|
||||
|
|
@ -445,7 +445,7 @@ export function div(dividend,divisor) {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
27, // arithmetic:uniffi_arithmetic_fn_func_div
|
||||
31, // arithmetic:uniffi_arithmetic_fn_func_div
|
||||
FfiConverterU64.lower(dividend),
|
||||
FfiConverterU64.lower(divisor),
|
||||
)
|
||||
|
|
@ -479,7 +479,7 @@ export function equal(a,b) {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
28, // arithmetic:uniffi_arithmetic_fn_func_equal
|
||||
32, // arithmetic:uniffi_arithmetic_fn_func_equal
|
||||
FfiConverterU64.lower(a),
|
||||
FfiConverterU64.lower(b),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -452,7 +452,7 @@ export function getCustomTypesDemo(demo) {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
112, // custom_types:uniffi_custom_types_fn_func_get_custom_types_demo
|
||||
116, // custom_types:uniffi_custom_types_fn_func_get_custom_types_demo
|
||||
FfiConverterOptionalTypeCustomTypesDemo.lower(demo),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -344,7 +344,7 @@ export function gradient(value) {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
113, // external_types:uniffi_external_types_fn_func_gradient
|
||||
117, // external_types:uniffi_external_types_fn_func_gradient
|
||||
FfiConverterOptionalTypeLine.lower(value),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -596,7 +596,7 @@ export function logEvenNumbers(logger,items) {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
110, // fixture_callbacks:uniffi_fixture_callbacks_fn_func_log_even_numbers
|
||||
114, // fixture_callbacks:uniffi_fixture_callbacks_fn_func_log_even_numbers
|
||||
FfiConverterCallbackInterfaceLogger.lower(logger),
|
||||
FfiConverterSequencei32.lower(items),
|
||||
)
|
||||
|
|
@ -630,7 +630,7 @@ export function logEvenNumbersMainThread(logger,items) {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callSync(
|
||||
111, // fixture_callbacks:uniffi_fixture_callbacks_fn_func_log_even_numbers_main_thread
|
||||
115, // fixture_callbacks:uniffi_fixture_callbacks_fn_func_log_even_numbers_main_thread
|
||||
FfiConverterCallbackInterfaceLogger.lower(logger),
|
||||
FfiConverterSequencei32.lower(items),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -468,7 +468,7 @@ export function gradient(ln) {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
23, // geometry:uniffi_geometry_fn_func_gradient
|
||||
27, // geometry:uniffi_geometry_fn_func_gradient
|
||||
FfiConverterTypeLine.lower(ln),
|
||||
)
|
||||
}
|
||||
|
|
@ -501,7 +501,7 @@ export function intersection(ln1,ln2) {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
24, // geometry:uniffi_geometry_fn_func_intersection
|
||||
28, // geometry:uniffi_geometry_fn_func_intersection
|
||||
FfiConverterTypeLine.lower(ln1),
|
||||
FfiConverterTypeLine.lower(ln2),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ class ArrayBufferDataStream {
|
|||
// UniFFI Pointers are **always** 8 bytes long. That is enforced
|
||||
// by the C++ and Rust Scaffolding code.
|
||||
readPointerRetourneur() {
|
||||
const pointerId = 3; // rondpoint:Retourneur
|
||||
const pointerId = 4; // rondpoint:Retourneur
|
||||
const res = UniFFIScaffolding.readPointer(pointerId, this.dataView.buffer, this.pos);
|
||||
this.pos += 8;
|
||||
return res;
|
||||
|
|
@ -168,7 +168,7 @@ class ArrayBufferDataStream {
|
|||
// UniFFI Pointers are **always** 8 bytes long. That is enforced
|
||||
// by the C++ and Rust Scaffolding code.
|
||||
writePointerRetourneur(value) {
|
||||
const pointerId = 3; // rondpoint:Retourneur
|
||||
const pointerId = 4; // rondpoint:Retourneur
|
||||
UniFFIScaffolding.writePointer(pointerId, value, this.dataView.buffer, this.pos);
|
||||
this.pos += 8;
|
||||
}
|
||||
|
|
@ -178,7 +178,7 @@ class ArrayBufferDataStream {
|
|||
// UniFFI Pointers are **always** 8 bytes long. That is enforced
|
||||
// by the C++ and Rust Scaffolding code.
|
||||
readPointerStringifier() {
|
||||
const pointerId = 4; // rondpoint:Stringifier
|
||||
const pointerId = 5; // rondpoint:Stringifier
|
||||
const res = UniFFIScaffolding.readPointer(pointerId, this.dataView.buffer, this.pos);
|
||||
this.pos += 8;
|
||||
return res;
|
||||
|
|
@ -188,7 +188,7 @@ class ArrayBufferDataStream {
|
|||
// UniFFI Pointers are **always** 8 bytes long. That is enforced
|
||||
// by the C++ and Rust Scaffolding code.
|
||||
writePointerStringifier(value) {
|
||||
const pointerId = 4; // rondpoint:Stringifier
|
||||
const pointerId = 5; // rondpoint:Stringifier
|
||||
UniFFIScaffolding.writePointer(pointerId, value, this.dataView.buffer, this.pos);
|
||||
this.pos += 8;
|
||||
}
|
||||
|
|
@ -198,7 +198,7 @@ class ArrayBufferDataStream {
|
|||
// UniFFI Pointers are **always** 8 bytes long. That is enforced
|
||||
// by the C++ and Rust Scaffolding code.
|
||||
readPointerOptionneur() {
|
||||
const pointerId = 5; // rondpoint:Optionneur
|
||||
const pointerId = 6; // rondpoint:Optionneur
|
||||
const res = UniFFIScaffolding.readPointer(pointerId, this.dataView.buffer, this.pos);
|
||||
this.pos += 8;
|
||||
return res;
|
||||
|
|
@ -208,7 +208,7 @@ class ArrayBufferDataStream {
|
|||
// UniFFI Pointers are **always** 8 bytes long. That is enforced
|
||||
// by the C++ and Rust Scaffolding code.
|
||||
writePointerOptionneur(value) {
|
||||
const pointerId = 5; // rondpoint:Optionneur
|
||||
const pointerId = 6; // rondpoint:Optionneur
|
||||
UniFFIScaffolding.writePointer(pointerId, value, this.dataView.buffer, this.pos);
|
||||
this.pos += 8;
|
||||
}
|
||||
|
|
@ -620,7 +620,7 @@ export class Optionneur {
|
|||
const liftError = null;
|
||||
const functionCall = () => {
|
||||
return UniFFIScaffolding.callAsync(
|
||||
58, // rondpoint:uniffi_rondpoint_fn_constructor_optionneur_new
|
||||
62, // rondpoint:uniffi_rondpoint_fn_constructor_optionneur_new
|
||||
)
|
||||
}
|
||||
try {
|
||||
|
|
@ -642,7 +642,7 @@ export class Optionneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
59, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_boolean
|
||||
63, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_boolean
|
||||
FfiConverterTypeOptionneur.lower(this),
|
||||
FfiConverterBool.lower(value),
|
||||
)
|
||||
|
|
@ -667,7 +667,7 @@ export class Optionneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
60, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_string
|
||||
64, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_string
|
||||
FfiConverterTypeOptionneur.lower(this),
|
||||
FfiConverterString.lower(value),
|
||||
)
|
||||
|
|
@ -692,7 +692,7 @@ export class Optionneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
61, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_sequence
|
||||
65, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_sequence
|
||||
FfiConverterTypeOptionneur.lower(this),
|
||||
FfiConverterSequencestring.lower(value),
|
||||
)
|
||||
|
|
@ -717,7 +717,7 @@ export class Optionneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
62, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_null
|
||||
66, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_null
|
||||
FfiConverterTypeOptionneur.lower(this),
|
||||
FfiConverterOptionalstring.lower(value),
|
||||
)
|
||||
|
|
@ -742,7 +742,7 @@ export class Optionneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
63, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_zero
|
||||
67, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_zero
|
||||
FfiConverterTypeOptionneur.lower(this),
|
||||
FfiConverterOptionali32.lower(value),
|
||||
)
|
||||
|
|
@ -767,7 +767,7 @@ export class Optionneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
64, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_u8_dec
|
||||
68, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_u8_dec
|
||||
FfiConverterTypeOptionneur.lower(this),
|
||||
FfiConverterU8.lower(value),
|
||||
)
|
||||
|
|
@ -792,7 +792,7 @@ export class Optionneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
65, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_i8_dec
|
||||
69, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_i8_dec
|
||||
FfiConverterTypeOptionneur.lower(this),
|
||||
FfiConverterI8.lower(value),
|
||||
)
|
||||
|
|
@ -817,7 +817,7 @@ export class Optionneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
66, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_u16_dec
|
||||
70, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_u16_dec
|
||||
FfiConverterTypeOptionneur.lower(this),
|
||||
FfiConverterU16.lower(value),
|
||||
)
|
||||
|
|
@ -842,7 +842,7 @@ export class Optionneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
67, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_i16_dec
|
||||
71, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_i16_dec
|
||||
FfiConverterTypeOptionneur.lower(this),
|
||||
FfiConverterI16.lower(value),
|
||||
)
|
||||
|
|
@ -867,7 +867,7 @@ export class Optionneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
68, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_u32_dec
|
||||
72, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_u32_dec
|
||||
FfiConverterTypeOptionneur.lower(this),
|
||||
FfiConverterU32.lower(value),
|
||||
)
|
||||
|
|
@ -892,7 +892,7 @@ export class Optionneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
69, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_i32_dec
|
||||
73, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_i32_dec
|
||||
FfiConverterTypeOptionneur.lower(this),
|
||||
FfiConverterI32.lower(value),
|
||||
)
|
||||
|
|
@ -917,7 +917,7 @@ export class Optionneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
70, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_u64_dec
|
||||
74, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_u64_dec
|
||||
FfiConverterTypeOptionneur.lower(this),
|
||||
FfiConverterU64.lower(value),
|
||||
)
|
||||
|
|
@ -942,7 +942,7 @@ export class Optionneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
71, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_i64_dec
|
||||
75, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_i64_dec
|
||||
FfiConverterTypeOptionneur.lower(this),
|
||||
FfiConverterI64.lower(value),
|
||||
)
|
||||
|
|
@ -967,7 +967,7 @@ export class Optionneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
72, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_u8_hex
|
||||
76, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_u8_hex
|
||||
FfiConverterTypeOptionneur.lower(this),
|
||||
FfiConverterU8.lower(value),
|
||||
)
|
||||
|
|
@ -992,7 +992,7 @@ export class Optionneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
73, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_i8_hex
|
||||
77, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_i8_hex
|
||||
FfiConverterTypeOptionneur.lower(this),
|
||||
FfiConverterI8.lower(value),
|
||||
)
|
||||
|
|
@ -1017,7 +1017,7 @@ export class Optionneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
74, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_u16_hex
|
||||
78, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_u16_hex
|
||||
FfiConverterTypeOptionneur.lower(this),
|
||||
FfiConverterU16.lower(value),
|
||||
)
|
||||
|
|
@ -1042,7 +1042,7 @@ export class Optionneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
75, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_i16_hex
|
||||
79, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_i16_hex
|
||||
FfiConverterTypeOptionneur.lower(this),
|
||||
FfiConverterI16.lower(value),
|
||||
)
|
||||
|
|
@ -1067,7 +1067,7 @@ export class Optionneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
76, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_u32_hex
|
||||
80, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_u32_hex
|
||||
FfiConverterTypeOptionneur.lower(this),
|
||||
FfiConverterU32.lower(value),
|
||||
)
|
||||
|
|
@ -1092,7 +1092,7 @@ export class Optionneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
77, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_i32_hex
|
||||
81, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_i32_hex
|
||||
FfiConverterTypeOptionneur.lower(this),
|
||||
FfiConverterI32.lower(value),
|
||||
)
|
||||
|
|
@ -1117,7 +1117,7 @@ export class Optionneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
78, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_u64_hex
|
||||
82, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_u64_hex
|
||||
FfiConverterTypeOptionneur.lower(this),
|
||||
FfiConverterU64.lower(value),
|
||||
)
|
||||
|
|
@ -1142,7 +1142,7 @@ export class Optionneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
79, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_i64_hex
|
||||
83, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_i64_hex
|
||||
FfiConverterTypeOptionneur.lower(this),
|
||||
FfiConverterI64.lower(value),
|
||||
)
|
||||
|
|
@ -1167,7 +1167,7 @@ export class Optionneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
80, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_u32_oct
|
||||
84, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_u32_oct
|
||||
FfiConverterTypeOptionneur.lower(this),
|
||||
FfiConverterU32.lower(value),
|
||||
)
|
||||
|
|
@ -1192,7 +1192,7 @@ export class Optionneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
81, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_f32
|
||||
85, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_f32
|
||||
FfiConverterTypeOptionneur.lower(this),
|
||||
FfiConverterF32.lower(value),
|
||||
)
|
||||
|
|
@ -1217,7 +1217,7 @@ export class Optionneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
82, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_f64
|
||||
86, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_f64
|
||||
FfiConverterTypeOptionneur.lower(this),
|
||||
FfiConverterF64.lower(value),
|
||||
)
|
||||
|
|
@ -1242,7 +1242,7 @@ export class Optionneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
83, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_enum
|
||||
87, // rondpoint:uniffi_rondpoint_fn_method_optionneur_sinon_enum
|
||||
FfiConverterTypeOptionneur.lower(this),
|
||||
FfiConverterTypeEnumeration.lower(value),
|
||||
)
|
||||
|
|
@ -1305,7 +1305,7 @@ export class Retourneur {
|
|||
const liftError = null;
|
||||
const functionCall = () => {
|
||||
return UniFFIScaffolding.callAsync(
|
||||
29, // rondpoint:uniffi_rondpoint_fn_constructor_retourneur_new
|
||||
33, // rondpoint:uniffi_rondpoint_fn_constructor_retourneur_new
|
||||
)
|
||||
}
|
||||
try {
|
||||
|
|
@ -1327,7 +1327,7 @@ export class Retourneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
30, // rondpoint:uniffi_rondpoint_fn_method_retourneur_identique_i8
|
||||
34, // rondpoint:uniffi_rondpoint_fn_method_retourneur_identique_i8
|
||||
FfiConverterTypeRetourneur.lower(this),
|
||||
FfiConverterI8.lower(value),
|
||||
)
|
||||
|
|
@ -1352,7 +1352,7 @@ export class Retourneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
31, // rondpoint:uniffi_rondpoint_fn_method_retourneur_identique_u8
|
||||
35, // rondpoint:uniffi_rondpoint_fn_method_retourneur_identique_u8
|
||||
FfiConverterTypeRetourneur.lower(this),
|
||||
FfiConverterU8.lower(value),
|
||||
)
|
||||
|
|
@ -1377,7 +1377,7 @@ export class Retourneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
32, // rondpoint:uniffi_rondpoint_fn_method_retourneur_identique_i16
|
||||
36, // rondpoint:uniffi_rondpoint_fn_method_retourneur_identique_i16
|
||||
FfiConverterTypeRetourneur.lower(this),
|
||||
FfiConverterI16.lower(value),
|
||||
)
|
||||
|
|
@ -1402,7 +1402,7 @@ export class Retourneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
33, // rondpoint:uniffi_rondpoint_fn_method_retourneur_identique_u16
|
||||
37, // rondpoint:uniffi_rondpoint_fn_method_retourneur_identique_u16
|
||||
FfiConverterTypeRetourneur.lower(this),
|
||||
FfiConverterU16.lower(value),
|
||||
)
|
||||
|
|
@ -1427,7 +1427,7 @@ export class Retourneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
34, // rondpoint:uniffi_rondpoint_fn_method_retourneur_identique_i32
|
||||
38, // rondpoint:uniffi_rondpoint_fn_method_retourneur_identique_i32
|
||||
FfiConverterTypeRetourneur.lower(this),
|
||||
FfiConverterI32.lower(value),
|
||||
)
|
||||
|
|
@ -1452,7 +1452,7 @@ export class Retourneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
35, // rondpoint:uniffi_rondpoint_fn_method_retourneur_identique_u32
|
||||
39, // rondpoint:uniffi_rondpoint_fn_method_retourneur_identique_u32
|
||||
FfiConverterTypeRetourneur.lower(this),
|
||||
FfiConverterU32.lower(value),
|
||||
)
|
||||
|
|
@ -1477,7 +1477,7 @@ export class Retourneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
36, // rondpoint:uniffi_rondpoint_fn_method_retourneur_identique_i64
|
||||
40, // rondpoint:uniffi_rondpoint_fn_method_retourneur_identique_i64
|
||||
FfiConverterTypeRetourneur.lower(this),
|
||||
FfiConverterI64.lower(value),
|
||||
)
|
||||
|
|
@ -1502,7 +1502,7 @@ export class Retourneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
37, // rondpoint:uniffi_rondpoint_fn_method_retourneur_identique_u64
|
||||
41, // rondpoint:uniffi_rondpoint_fn_method_retourneur_identique_u64
|
||||
FfiConverterTypeRetourneur.lower(this),
|
||||
FfiConverterU64.lower(value),
|
||||
)
|
||||
|
|
@ -1527,7 +1527,7 @@ export class Retourneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
38, // rondpoint:uniffi_rondpoint_fn_method_retourneur_identique_float
|
||||
42, // rondpoint:uniffi_rondpoint_fn_method_retourneur_identique_float
|
||||
FfiConverterTypeRetourneur.lower(this),
|
||||
FfiConverterF32.lower(value),
|
||||
)
|
||||
|
|
@ -1552,7 +1552,7 @@ export class Retourneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
39, // rondpoint:uniffi_rondpoint_fn_method_retourneur_identique_double
|
||||
43, // rondpoint:uniffi_rondpoint_fn_method_retourneur_identique_double
|
||||
FfiConverterTypeRetourneur.lower(this),
|
||||
FfiConverterF64.lower(value),
|
||||
)
|
||||
|
|
@ -1577,7 +1577,7 @@ export class Retourneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
40, // rondpoint:uniffi_rondpoint_fn_method_retourneur_identique_boolean
|
||||
44, // rondpoint:uniffi_rondpoint_fn_method_retourneur_identique_boolean
|
||||
FfiConverterTypeRetourneur.lower(this),
|
||||
FfiConverterBool.lower(value),
|
||||
)
|
||||
|
|
@ -1602,7 +1602,7 @@ export class Retourneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
41, // rondpoint:uniffi_rondpoint_fn_method_retourneur_identique_string
|
||||
45, // rondpoint:uniffi_rondpoint_fn_method_retourneur_identique_string
|
||||
FfiConverterTypeRetourneur.lower(this),
|
||||
FfiConverterString.lower(value),
|
||||
)
|
||||
|
|
@ -1627,7 +1627,7 @@ export class Retourneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
42, // rondpoint:uniffi_rondpoint_fn_method_retourneur_identique_nombres_signes
|
||||
46, // rondpoint:uniffi_rondpoint_fn_method_retourneur_identique_nombres_signes
|
||||
FfiConverterTypeRetourneur.lower(this),
|
||||
FfiConverterTypeDictionnaireNombresSignes.lower(value),
|
||||
)
|
||||
|
|
@ -1652,7 +1652,7 @@ export class Retourneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
43, // rondpoint:uniffi_rondpoint_fn_method_retourneur_identique_nombres
|
||||
47, // rondpoint:uniffi_rondpoint_fn_method_retourneur_identique_nombres
|
||||
FfiConverterTypeRetourneur.lower(this),
|
||||
FfiConverterTypeDictionnaireNombres.lower(value),
|
||||
)
|
||||
|
|
@ -1677,7 +1677,7 @@ export class Retourneur {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
44, // rondpoint:uniffi_rondpoint_fn_method_retourneur_identique_optionneur_dictionnaire
|
||||
48, // rondpoint:uniffi_rondpoint_fn_method_retourneur_identique_optionneur_dictionnaire
|
||||
FfiConverterTypeRetourneur.lower(this),
|
||||
FfiConverterTypeOptionneurDictionnaire.lower(value),
|
||||
)
|
||||
|
|
@ -1740,7 +1740,7 @@ export class Stringifier {
|
|||
const liftError = null;
|
||||
const functionCall = () => {
|
||||
return UniFFIScaffolding.callAsync(
|
||||
45, // rondpoint:uniffi_rondpoint_fn_constructor_stringifier_new
|
||||
49, // rondpoint:uniffi_rondpoint_fn_constructor_stringifier_new
|
||||
)
|
||||
}
|
||||
try {
|
||||
|
|
@ -1762,7 +1762,7 @@ export class Stringifier {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
46, // rondpoint:uniffi_rondpoint_fn_method_stringifier_well_known_string
|
||||
50, // rondpoint:uniffi_rondpoint_fn_method_stringifier_well_known_string
|
||||
FfiConverterTypeStringifier.lower(this),
|
||||
FfiConverterString.lower(value),
|
||||
)
|
||||
|
|
@ -1787,7 +1787,7 @@ export class Stringifier {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
47, // rondpoint:uniffi_rondpoint_fn_method_stringifier_to_string_i8
|
||||
51, // rondpoint:uniffi_rondpoint_fn_method_stringifier_to_string_i8
|
||||
FfiConverterTypeStringifier.lower(this),
|
||||
FfiConverterI8.lower(value),
|
||||
)
|
||||
|
|
@ -1812,7 +1812,7 @@ export class Stringifier {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
48, // rondpoint:uniffi_rondpoint_fn_method_stringifier_to_string_u8
|
||||
52, // rondpoint:uniffi_rondpoint_fn_method_stringifier_to_string_u8
|
||||
FfiConverterTypeStringifier.lower(this),
|
||||
FfiConverterU8.lower(value),
|
||||
)
|
||||
|
|
@ -1837,7 +1837,7 @@ export class Stringifier {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
49, // rondpoint:uniffi_rondpoint_fn_method_stringifier_to_string_i16
|
||||
53, // rondpoint:uniffi_rondpoint_fn_method_stringifier_to_string_i16
|
||||
FfiConverterTypeStringifier.lower(this),
|
||||
FfiConverterI16.lower(value),
|
||||
)
|
||||
|
|
@ -1862,7 +1862,7 @@ export class Stringifier {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
50, // rondpoint:uniffi_rondpoint_fn_method_stringifier_to_string_u16
|
||||
54, // rondpoint:uniffi_rondpoint_fn_method_stringifier_to_string_u16
|
||||
FfiConverterTypeStringifier.lower(this),
|
||||
FfiConverterU16.lower(value),
|
||||
)
|
||||
|
|
@ -1887,7 +1887,7 @@ export class Stringifier {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
51, // rondpoint:uniffi_rondpoint_fn_method_stringifier_to_string_i32
|
||||
55, // rondpoint:uniffi_rondpoint_fn_method_stringifier_to_string_i32
|
||||
FfiConverterTypeStringifier.lower(this),
|
||||
FfiConverterI32.lower(value),
|
||||
)
|
||||
|
|
@ -1912,7 +1912,7 @@ export class Stringifier {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
52, // rondpoint:uniffi_rondpoint_fn_method_stringifier_to_string_u32
|
||||
56, // rondpoint:uniffi_rondpoint_fn_method_stringifier_to_string_u32
|
||||
FfiConverterTypeStringifier.lower(this),
|
||||
FfiConverterU32.lower(value),
|
||||
)
|
||||
|
|
@ -1937,7 +1937,7 @@ export class Stringifier {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
53, // rondpoint:uniffi_rondpoint_fn_method_stringifier_to_string_i64
|
||||
57, // rondpoint:uniffi_rondpoint_fn_method_stringifier_to_string_i64
|
||||
FfiConverterTypeStringifier.lower(this),
|
||||
FfiConverterI64.lower(value),
|
||||
)
|
||||
|
|
@ -1962,7 +1962,7 @@ export class Stringifier {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
54, // rondpoint:uniffi_rondpoint_fn_method_stringifier_to_string_u64
|
||||
58, // rondpoint:uniffi_rondpoint_fn_method_stringifier_to_string_u64
|
||||
FfiConverterTypeStringifier.lower(this),
|
||||
FfiConverterU64.lower(value),
|
||||
)
|
||||
|
|
@ -1987,7 +1987,7 @@ export class Stringifier {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
55, // rondpoint:uniffi_rondpoint_fn_method_stringifier_to_string_float
|
||||
59, // rondpoint:uniffi_rondpoint_fn_method_stringifier_to_string_float
|
||||
FfiConverterTypeStringifier.lower(this),
|
||||
FfiConverterF32.lower(value),
|
||||
)
|
||||
|
|
@ -2012,7 +2012,7 @@ export class Stringifier {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
56, // rondpoint:uniffi_rondpoint_fn_method_stringifier_to_string_double
|
||||
60, // rondpoint:uniffi_rondpoint_fn_method_stringifier_to_string_double
|
||||
FfiConverterTypeStringifier.lower(this),
|
||||
FfiConverterF64.lower(value),
|
||||
)
|
||||
|
|
@ -2037,7 +2037,7 @@ export class Stringifier {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
57, // rondpoint:uniffi_rondpoint_fn_method_stringifier_to_string_boolean
|
||||
61, // rondpoint:uniffi_rondpoint_fn_method_stringifier_to_string_boolean
|
||||
FfiConverterTypeStringifier.lower(this),
|
||||
FfiConverterBool.lower(value),
|
||||
)
|
||||
|
|
@ -3257,7 +3257,7 @@ export function copieDictionnaire(d) {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
84, // rondpoint:uniffi_rondpoint_fn_func_copie_dictionnaire
|
||||
88, // rondpoint:uniffi_rondpoint_fn_func_copie_dictionnaire
|
||||
FfiConverterTypeDictionnaire.lower(d),
|
||||
)
|
||||
}
|
||||
|
|
@ -3282,7 +3282,7 @@ export function copieEnumeration(e) {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
85, // rondpoint:uniffi_rondpoint_fn_func_copie_enumeration
|
||||
89, // rondpoint:uniffi_rondpoint_fn_func_copie_enumeration
|
||||
FfiConverterTypeEnumeration.lower(e),
|
||||
)
|
||||
}
|
||||
|
|
@ -3307,7 +3307,7 @@ export function copieEnumerations(e) {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
86, // rondpoint:uniffi_rondpoint_fn_func_copie_enumerations
|
||||
90, // rondpoint:uniffi_rondpoint_fn_func_copie_enumerations
|
||||
FfiConverterSequenceTypeEnumeration.lower(e),
|
||||
)
|
||||
}
|
||||
|
|
@ -3332,7 +3332,7 @@ export function copieCarte(c) {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
87, // rondpoint:uniffi_rondpoint_fn_func_copie_carte
|
||||
91, // rondpoint:uniffi_rondpoint_fn_func_copie_carte
|
||||
FfiConverterMapStringTypeEnumerationAvecDonnees.lower(c),
|
||||
)
|
||||
}
|
||||
|
|
@ -3357,7 +3357,7 @@ export function switcheroo(b) {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
88, // rondpoint:uniffi_rondpoint_fn_func_switcheroo
|
||||
92, // rondpoint:uniffi_rondpoint_fn_func_switcheroo
|
||||
FfiConverterBool.lower(b),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ class ArrayBufferDataStream {
|
|||
// UniFFI Pointers are **always** 8 bytes long. That is enforced
|
||||
// by the C++ and Rust Scaffolding code.
|
||||
readPointerSprite() {
|
||||
const pointerId = 6; // sprites:Sprite
|
||||
const pointerId = 7; // sprites:Sprite
|
||||
const res = UniFFIScaffolding.readPointer(pointerId, this.dataView.buffer, this.pos);
|
||||
this.pos += 8;
|
||||
return res;
|
||||
|
|
@ -168,7 +168,7 @@ class ArrayBufferDataStream {
|
|||
// UniFFI Pointers are **always** 8 bytes long. That is enforced
|
||||
// by the C++ and Rust Scaffolding code.
|
||||
writePointerSprite(value) {
|
||||
const pointerId = 6; // sprites:Sprite
|
||||
const pointerId = 7; // sprites:Sprite
|
||||
UniFFIScaffolding.writePointer(pointerId, value, this.dataView.buffer, this.pos);
|
||||
this.pos += 8;
|
||||
}
|
||||
|
|
@ -325,7 +325,7 @@ export class Sprite {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
89, // sprites:uniffi_sprites_fn_constructor_sprite_new
|
||||
93, // sprites:uniffi_sprites_fn_constructor_sprite_new
|
||||
FfiConverterOptionalTypePoint.lower(initialPosition),
|
||||
)
|
||||
}
|
||||
|
|
@ -361,7 +361,7 @@ export class Sprite {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
90, // sprites:uniffi_sprites_fn_constructor_sprite_new_relative_to
|
||||
94, // sprites:uniffi_sprites_fn_constructor_sprite_new_relative_to
|
||||
FfiConverterTypePoint.lower(reference),
|
||||
FfiConverterTypeVector.lower(direction),
|
||||
)
|
||||
|
|
@ -377,7 +377,7 @@ export class Sprite {
|
|||
const liftError = null;
|
||||
const functionCall = () => {
|
||||
return UniFFIScaffolding.callAsync(
|
||||
91, // sprites:uniffi_sprites_fn_method_sprite_get_position
|
||||
95, // sprites:uniffi_sprites_fn_method_sprite_get_position
|
||||
FfiConverterTypeSprite.lower(this),
|
||||
)
|
||||
}
|
||||
|
|
@ -401,7 +401,7 @@ export class Sprite {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
92, // sprites:uniffi_sprites_fn_method_sprite_move_to
|
||||
96, // sprites:uniffi_sprites_fn_method_sprite_move_to
|
||||
FfiConverterTypeSprite.lower(this),
|
||||
FfiConverterTypePoint.lower(position),
|
||||
)
|
||||
|
|
@ -426,7 +426,7 @@ export class Sprite {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
93, // sprites:uniffi_sprites_fn_method_sprite_move_by
|
||||
97, // sprites:uniffi_sprites_fn_method_sprite_move_by
|
||||
FfiConverterTypeSprite.lower(this),
|
||||
FfiConverterTypeVector.lower(direction),
|
||||
)
|
||||
|
|
@ -668,7 +668,7 @@ export function translate(position,direction) {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
94, // sprites:uniffi_sprites_fn_func_translate
|
||||
98, // sprites:uniffi_sprites_fn_func_translate
|
||||
FfiConverterTypePoint.lower(position),
|
||||
FfiConverterTypeVector.lower(direction),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ class ArrayBufferDataStream {
|
|||
// UniFFI Pointers are **always** 8 bytes long. That is enforced
|
||||
// by the C++ and Rust Scaffolding code.
|
||||
readPointerTodoList() {
|
||||
const pointerId = 7; // todolist:TodoList
|
||||
const pointerId = 8; // todolist:TodoList
|
||||
const res = UniFFIScaffolding.readPointer(pointerId, this.dataView.buffer, this.pos);
|
||||
this.pos += 8;
|
||||
return res;
|
||||
|
|
@ -168,7 +168,7 @@ class ArrayBufferDataStream {
|
|||
// UniFFI Pointers are **always** 8 bytes long. That is enforced
|
||||
// by the C++ and Rust Scaffolding code.
|
||||
writePointerTodoList(value) {
|
||||
const pointerId = 7; // todolist:TodoList
|
||||
const pointerId = 8; // todolist:TodoList
|
||||
UniFFIScaffolding.writePointer(pointerId, value, this.dataView.buffer, this.pos);
|
||||
this.pos += 8;
|
||||
}
|
||||
|
|
@ -298,7 +298,7 @@ export class TodoList {
|
|||
const liftError = null;
|
||||
const functionCall = () => {
|
||||
return UniFFIScaffolding.callAsync(
|
||||
95, // todolist:uniffi_todolist_fn_constructor_todolist_new
|
||||
99, // todolist:uniffi_todolist_fn_constructor_todolist_new
|
||||
)
|
||||
}
|
||||
try {
|
||||
|
|
@ -320,7 +320,7 @@ export class TodoList {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
96, // todolist:uniffi_todolist_fn_method_todolist_add_item
|
||||
100, // todolist:uniffi_todolist_fn_method_todolist_add_item
|
||||
FfiConverterTypeTodoList.lower(this),
|
||||
FfiConverterString.lower(todo),
|
||||
)
|
||||
|
|
@ -345,7 +345,7 @@ export class TodoList {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
97, // todolist:uniffi_todolist_fn_method_todolist_add_entry
|
||||
101, // todolist:uniffi_todolist_fn_method_todolist_add_entry
|
||||
FfiConverterTypeTodoList.lower(this),
|
||||
FfiConverterTypeTodoEntry.lower(entry),
|
||||
)
|
||||
|
|
@ -362,7 +362,7 @@ export class TodoList {
|
|||
const liftError = null;
|
||||
const functionCall = () => {
|
||||
return UniFFIScaffolding.callAsync(
|
||||
98, // todolist:uniffi_todolist_fn_method_todolist_get_entries
|
||||
102, // todolist:uniffi_todolist_fn_method_todolist_get_entries
|
||||
FfiConverterTypeTodoList.lower(this),
|
||||
)
|
||||
}
|
||||
|
|
@ -378,7 +378,7 @@ export class TodoList {
|
|||
const liftError = null;
|
||||
const functionCall = () => {
|
||||
return UniFFIScaffolding.callAsync(
|
||||
99, // todolist:uniffi_todolist_fn_method_todolist_get_items
|
||||
103, // todolist:uniffi_todolist_fn_method_todolist_get_items
|
||||
FfiConverterTypeTodoList.lower(this),
|
||||
)
|
||||
}
|
||||
|
|
@ -402,7 +402,7 @@ export class TodoList {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
100, // todolist:uniffi_todolist_fn_method_todolist_add_entries
|
||||
104, // todolist:uniffi_todolist_fn_method_todolist_add_entries
|
||||
FfiConverterTypeTodoList.lower(this),
|
||||
FfiConverterSequenceTypeTodoEntry.lower(entries),
|
||||
)
|
||||
|
|
@ -427,7 +427,7 @@ export class TodoList {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
101, // todolist:uniffi_todolist_fn_method_todolist_add_items
|
||||
105, // todolist:uniffi_todolist_fn_method_todolist_add_items
|
||||
FfiConverterTypeTodoList.lower(this),
|
||||
FfiConverterSequencestring.lower(items),
|
||||
)
|
||||
|
|
@ -444,7 +444,7 @@ export class TodoList {
|
|||
const liftError = (data) => FfiConverterTypeTodoError.lift(data);
|
||||
const functionCall = () => {
|
||||
return UniFFIScaffolding.callAsync(
|
||||
102, // todolist:uniffi_todolist_fn_method_todolist_get_last_entry
|
||||
106, // todolist:uniffi_todolist_fn_method_todolist_get_last_entry
|
||||
FfiConverterTypeTodoList.lower(this),
|
||||
)
|
||||
}
|
||||
|
|
@ -460,7 +460,7 @@ export class TodoList {
|
|||
const liftError = (data) => FfiConverterTypeTodoError.lift(data);
|
||||
const functionCall = () => {
|
||||
return UniFFIScaffolding.callAsync(
|
||||
103, // todolist:uniffi_todolist_fn_method_todolist_get_last
|
||||
107, // todolist:uniffi_todolist_fn_method_todolist_get_last
|
||||
FfiConverterTypeTodoList.lower(this),
|
||||
)
|
||||
}
|
||||
|
|
@ -476,7 +476,7 @@ export class TodoList {
|
|||
const liftError = (data) => FfiConverterTypeTodoError.lift(data);
|
||||
const functionCall = () => {
|
||||
return UniFFIScaffolding.callAsync(
|
||||
104, // todolist:uniffi_todolist_fn_method_todolist_get_first
|
||||
108, // todolist:uniffi_todolist_fn_method_todolist_get_first
|
||||
FfiConverterTypeTodoList.lower(this),
|
||||
)
|
||||
}
|
||||
|
|
@ -500,7 +500,7 @@ export class TodoList {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
105, // todolist:uniffi_todolist_fn_method_todolist_clear_item
|
||||
109, // todolist:uniffi_todolist_fn_method_todolist_clear_item
|
||||
FfiConverterTypeTodoList.lower(this),
|
||||
FfiConverterString.lower(todo),
|
||||
)
|
||||
|
|
@ -517,7 +517,7 @@ export class TodoList {
|
|||
const liftError = null;
|
||||
const functionCall = () => {
|
||||
return UniFFIScaffolding.callAsync(
|
||||
106, // todolist:uniffi_todolist_fn_method_todolist_make_default
|
||||
110, // todolist:uniffi_todolist_fn_method_todolist_make_default
|
||||
FfiConverterTypeTodoList.lower(this),
|
||||
)
|
||||
}
|
||||
|
|
@ -865,7 +865,7 @@ export function getDefaultList() {
|
|||
const liftError = null;
|
||||
const functionCall = () => {
|
||||
return UniFFIScaffolding.callAsync(
|
||||
107, // todolist:uniffi_todolist_fn_func_get_default_list
|
||||
111, // todolist:uniffi_todolist_fn_func_get_default_list
|
||||
)
|
||||
}
|
||||
try {
|
||||
|
|
@ -889,7 +889,7 @@ export function setDefaultList(list) {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
108, // todolist:uniffi_todolist_fn_func_set_default_list
|
||||
112, // todolist:uniffi_todolist_fn_func_set_default_list
|
||||
FfiConverterTypeTodoList.lower(list),
|
||||
)
|
||||
}
|
||||
|
|
@ -914,7 +914,7 @@ export function createEntryWith(todo) {
|
|||
throw e;
|
||||
}
|
||||
return UniFFIScaffolding.callAsync(
|
||||
109, // todolist:uniffi_todolist_fn_func_create_entry_with
|
||||
113, // todolist:uniffi_todolist_fn_func_create_entry_with
|
||||
FfiConverterString.lower(todo),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ UDL_FILES = [
|
|||
"third_party/rust/sync15/src/sync15.udl",
|
||||
"third_party/rust/tabs/src/tabs.udl",
|
||||
"third_party/rust/suggest/src/suggest.udl",
|
||||
"third_party/rust/remote_settings/src/remote_settings.udl",
|
||||
]
|
||||
|
||||
FIXTURE_UDL_FILES = [
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -50,6 +50,11 @@ extern "C" {
|
|||
void uniffi_suggest_fn_method_suggeststore_interrupt(void *, RustCallStatus*);
|
||||
void uniffi_suggest_fn_method_suggeststore_ingest(void *, RustBuffer, RustCallStatus*);
|
||||
void uniffi_suggest_fn_method_suggeststore_clear(void *, RustCallStatus*);
|
||||
void uniffi_remote_settings_fn_free_remotesettings(void *, RustCallStatus*);
|
||||
void * uniffi_remote_settings_fn_constructor_remotesettings_new(RustBuffer, RustCallStatus*);
|
||||
RustBuffer uniffi_remote_settings_fn_method_remotesettings_get_records(void *, RustCallStatus*);
|
||||
RustBuffer uniffi_remote_settings_fn_method_remotesettings_get_records_since(void *, uint64_t, RustCallStatus*);
|
||||
void uniffi_remote_settings_fn_method_remotesettings_download_attachment_to_path(void *, RustBuffer, RustBuffer, RustCallStatus*);
|
||||
}
|
||||
|
||||
// Define pointer types
|
||||
|
|
@ -65,6 +70,10 @@ const static mozilla::uniffi::UniFFIPointerType kSuggestSuggestStorePointerType
|
|||
"suggest::SuggestStore"_ns,
|
||||
uniffi_suggest_fn_free_suggeststore
|
||||
};
|
||||
const static mozilla::uniffi::UniFFIPointerType kRemoteSettingsRemoteSettingsPointerType {
|
||||
"remote_settings::RemoteSettings"_ns,
|
||||
uniffi_remote_settings_fn_free_remotesettings
|
||||
};
|
||||
|
||||
// Define the data we need per-callback interface
|
||||
|
||||
|
|
@ -171,6 +180,22 @@ Maybe<already_AddRefed<Promise>> UniFFICallAsync(const GlobalObject& aGlobal, ui
|
|||
using CallHandler = ScaffoldingCallHandler<ScaffoldingConverter<void>, ScaffoldingObjectConverter<&kSuggestSuggestStorePointerType>>;
|
||||
return Some(CallHandler::CallAsync(uniffi_suggest_fn_method_suggeststore_clear, aGlobal, aArgs, "uniffi_suggest_fn_method_suggeststore_clear: "_ns, aError));
|
||||
}
|
||||
case 23: { // remote_settings:uniffi_remote_settings_fn_constructor_remotesettings_new
|
||||
using CallHandler = ScaffoldingCallHandler<ScaffoldingObjectConverter<&kRemoteSettingsRemoteSettingsPointerType>, ScaffoldingConverter<RustBuffer>>;
|
||||
return Some(CallHandler::CallAsync(uniffi_remote_settings_fn_constructor_remotesettings_new, aGlobal, aArgs, "uniffi_remote_settings_fn_constructor_remotesettings_new: "_ns, aError));
|
||||
}
|
||||
case 24: { // remote_settings:uniffi_remote_settings_fn_method_remotesettings_get_records
|
||||
using CallHandler = ScaffoldingCallHandler<ScaffoldingConverter<RustBuffer>, ScaffoldingObjectConverter<&kRemoteSettingsRemoteSettingsPointerType>>;
|
||||
return Some(CallHandler::CallAsync(uniffi_remote_settings_fn_method_remotesettings_get_records, aGlobal, aArgs, "uniffi_remote_settings_fn_method_remotesettings_get_records: "_ns, aError));
|
||||
}
|
||||
case 25: { // remote_settings:uniffi_remote_settings_fn_method_remotesettings_get_records_since
|
||||
using CallHandler = ScaffoldingCallHandler<ScaffoldingConverter<RustBuffer>, ScaffoldingObjectConverter<&kRemoteSettingsRemoteSettingsPointerType>, ScaffoldingConverter<uint64_t>>;
|
||||
return Some(CallHandler::CallAsync(uniffi_remote_settings_fn_method_remotesettings_get_records_since, aGlobal, aArgs, "uniffi_remote_settings_fn_method_remotesettings_get_records_since: "_ns, aError));
|
||||
}
|
||||
case 26: { // remote_settings:uniffi_remote_settings_fn_method_remotesettings_download_attachment_to_path
|
||||
using CallHandler = ScaffoldingCallHandler<ScaffoldingConverter<void>, ScaffoldingObjectConverter<&kRemoteSettingsRemoteSettingsPointerType>, ScaffoldingConverter<RustBuffer>, ScaffoldingConverter<RustBuffer>>;
|
||||
return Some(CallHandler::CallAsync(uniffi_remote_settings_fn_method_remotesettings_download_attachment_to_path, aGlobal, aArgs, "uniffi_remote_settings_fn_method_remotesettings_download_attachment_to_path: "_ns, aError));
|
||||
}
|
||||
}
|
||||
return Nothing();
|
||||
}
|
||||
|
|
@ -292,6 +317,26 @@ bool UniFFICallSync(const GlobalObject& aGlobal, uint64_t aId, const Sequence<Sc
|
|||
CallHandler::CallSync(uniffi_suggest_fn_method_suggeststore_clear, aGlobal, aArgs, aReturnValue, "uniffi_suggest_fn_method_suggeststore_clear: "_ns, aError);
|
||||
return true;
|
||||
}
|
||||
case 23: { // remote_settings:uniffi_remote_settings_fn_constructor_remotesettings_new
|
||||
using CallHandler = ScaffoldingCallHandler<ScaffoldingObjectConverter<&kRemoteSettingsRemoteSettingsPointerType>, ScaffoldingConverter<RustBuffer>>;
|
||||
CallHandler::CallSync(uniffi_remote_settings_fn_constructor_remotesettings_new, aGlobal, aArgs, aReturnValue, "uniffi_remote_settings_fn_constructor_remotesettings_new: "_ns, aError);
|
||||
return true;
|
||||
}
|
||||
case 24: { // remote_settings:uniffi_remote_settings_fn_method_remotesettings_get_records
|
||||
using CallHandler = ScaffoldingCallHandler<ScaffoldingConverter<RustBuffer>, ScaffoldingObjectConverter<&kRemoteSettingsRemoteSettingsPointerType>>;
|
||||
CallHandler::CallSync(uniffi_remote_settings_fn_method_remotesettings_get_records, aGlobal, aArgs, aReturnValue, "uniffi_remote_settings_fn_method_remotesettings_get_records: "_ns, aError);
|
||||
return true;
|
||||
}
|
||||
case 25: { // remote_settings:uniffi_remote_settings_fn_method_remotesettings_get_records_since
|
||||
using CallHandler = ScaffoldingCallHandler<ScaffoldingConverter<RustBuffer>, ScaffoldingObjectConverter<&kRemoteSettingsRemoteSettingsPointerType>, ScaffoldingConverter<uint64_t>>;
|
||||
CallHandler::CallSync(uniffi_remote_settings_fn_method_remotesettings_get_records_since, aGlobal, aArgs, aReturnValue, "uniffi_remote_settings_fn_method_remotesettings_get_records_since: "_ns, aError);
|
||||
return true;
|
||||
}
|
||||
case 26: { // remote_settings:uniffi_remote_settings_fn_method_remotesettings_download_attachment_to_path
|
||||
using CallHandler = ScaffoldingCallHandler<ScaffoldingConverter<void>, ScaffoldingObjectConverter<&kRemoteSettingsRemoteSettingsPointerType>, ScaffoldingConverter<RustBuffer>, ScaffoldingConverter<RustBuffer>>;
|
||||
CallHandler::CallSync(uniffi_remote_settings_fn_method_remotesettings_download_attachment_to_path, aGlobal, aArgs, aReturnValue, "uniffi_remote_settings_fn_method_remotesettings_download_attachment_to_path: "_ns, aError);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -311,6 +356,10 @@ Maybe<already_AddRefed<UniFFIPointer>> UniFFIReadPointer(const GlobalObject& aGl
|
|||
type = &kSuggestSuggestStorePointerType;
|
||||
break;
|
||||
}
|
||||
case 3: { // remote_settings:RemoteSettings
|
||||
type = &kRemoteSettingsRemoteSettingsPointerType;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return Nothing();
|
||||
}
|
||||
|
|
@ -332,6 +381,10 @@ bool UniFFIWritePointer(const GlobalObject& aGlobal, uint64_t aId, const UniFFIP
|
|||
type = &kSuggestSuggestStorePointerType;
|
||||
break;
|
||||
}
|
||||
case 3: { // remote_settings:RemoteSettings
|
||||
type = &kRemoteSettingsRemoteSettingsPointerType;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue