Backed out 7 changesets (bug 1956132, bug 1956378, bug 1950665, bug 1953191) for causing LateWriteObserver crashes.
Backed out changeset 38ae4256b2ad (bug 1956132) Backed out changeset cc9d570bc0d1 (bug 1956378) Backed out changeset 85142db17376 (bug 1950665) Backed out changeset 251fd670f26e (bug 1953191) Backed out changeset f79d2c98afbc (bug 1953191) Backed out changeset 7d91be694ac1 (bug 1953191) Backed out changeset cb2b3aee545c (bug 1950665)
This commit is contained in:
@@ -70,9 +70,9 @@ git = "https://github.com/jfkthame/mapped_hyph.git"
|
||||
rev = "eff105f6ad7ec9b79816cfc1985a28e5340ad14b"
|
||||
replace-with = "vendored-sources"
|
||||
|
||||
[source."git+https://github.com/mozilla/application-services?rev=50c3f77fa264974678ec59e752fe7dc39c29900b"]
|
||||
[source."git+https://github.com/mozilla/application-services?rev=d773da92641d92930b7308300e9fc2746a05ce6a"]
|
||||
git = "https://github.com/mozilla/application-services"
|
||||
rev = "50c3f77fa264974678ec59e752fe7dc39c29900b"
|
||||
rev = "d773da92641d92930b7308300e9fc2746a05ce6a"
|
||||
replace-with = "vendored-sources"
|
||||
|
||||
[source."git+https://github.com/mozilla/audioipc?rev=e6f44a2bd1e57d11dfc737632a9e849077632330"]
|
||||
|
||||
212
Cargo.lock
generated
212
Cargo.lock
generated
@@ -189,6 +189,38 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "askama"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47cbc3cf73fa8d9833727bbee4835ba5c421a0d65b72daf9a7b5d0e0f9cfb57e"
|
||||
dependencies = [
|
||||
"askama_derive",
|
||||
"askama_escape",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "askama_derive"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c22fbe0413545c098358e56966ff22cdd039e10215ae213cfbd65032b119fc94"
|
||||
dependencies = [
|
||||
"basic-toml",
|
||||
"mime",
|
||||
"mime_guess",
|
||||
"nom",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "askama_escape"
|
||||
version = "0.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341"
|
||||
|
||||
[[package]]
|
||||
name = "async-task"
|
||||
version = "4.3.0"
|
||||
@@ -435,7 +467,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"rustc-hash 1.999.999",
|
||||
"rustc-hash",
|
||||
"shlex",
|
||||
"syn",
|
||||
]
|
||||
@@ -1783,7 +1815,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "error-support"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=50c3f77fa264974678ec59e752fe7dc39c29900b#50c3f77fa264974678ec59e752fe7dc39c29900b"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=d773da92641d92930b7308300e9fc2746a05ce6a#d773da92641d92930b7308300e9fc2746a05ce6a"
|
||||
dependencies = [
|
||||
"error-support-macros",
|
||||
"lazy_static",
|
||||
@@ -1795,7 +1827,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "error-support-macros"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=50c3f77fa264974678ec59e752fe7dc39c29900b#50c3f77fa264974678ec59e752fe7dc39c29900b"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=d773da92641d92930b7308300e9fc2746a05ce6a#d773da92641d92930b7308300e9fc2746a05ce6a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -1912,7 +1944,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "firefox-versioning"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=50c3f77fa264974678ec59e752fe7dc39c29900b#50c3f77fa264974678ec59e752fe7dc39c29900b"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=d773da92641d92930b7308300e9fc2746a05ce6a#d773da92641d92930b7308300e9fc2746a05ce6a"
|
||||
dependencies = [
|
||||
"serde_json",
|
||||
"thiserror 1.999.999",
|
||||
@@ -1964,7 +1996,7 @@ dependencies = [
|
||||
"fluent-syntax",
|
||||
"intl-memoizer",
|
||||
"intl_pluralrules",
|
||||
"rustc-hash 1.999.999",
|
||||
"rustc-hash",
|
||||
"self_cell",
|
||||
"smallvec",
|
||||
"unic-langid",
|
||||
@@ -1981,7 +2013,7 @@ dependencies = [
|
||||
"fluent-bundle",
|
||||
"futures",
|
||||
"once_cell",
|
||||
"rustc-hash 1.999.999",
|
||||
"rustc-hash",
|
||||
"unic-langid",
|
||||
]
|
||||
|
||||
@@ -2565,9 +2597,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "glean"
|
||||
version = "64.0.0"
|
||||
version = "63.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba92338cfd9fb34b00c02c6da8e22936b41835eb02ab5462d3d88cc4b6249c35"
|
||||
checksum = "e2afa6754943cac5243099efd0d26e89cc8e06f1585776ba14ab0c6ee99e1f71"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"glean-core",
|
||||
@@ -2579,9 +2611,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "glean-core"
|
||||
version = "64.0.0"
|
||||
version = "63.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92a2cbf41fbb9996b14fc1721b8bd06e669589de05e6efc20a24bab14285623a"
|
||||
checksum = "53cd53bb7a3b89b17d3989e95dd808b137ff47c504d1d19f14cb0d820cc2f42e"
|
||||
dependencies = [
|
||||
"android_logger",
|
||||
"bincode",
|
||||
@@ -3211,7 +3243,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "interrupt-support"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=50c3f77fa264974678ec59e752fe7dc39c29900b#50c3f77fa264974678ec59e752fe7dc39c29900b"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=d773da92641d92930b7308300e9fc2746a05ce6a#d773da92641d92930b7308300e9fc2746a05ce6a"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"parking_lot",
|
||||
@@ -3293,9 +3325,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.15"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
||||
checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
|
||||
|
||||
[[package]]
|
||||
name = "jexl-eval"
|
||||
@@ -3431,7 +3463,7 @@ dependencies = [
|
||||
"futures",
|
||||
"pin-project-lite",
|
||||
"replace_with",
|
||||
"rustc-hash 1.999.999",
|
||||
"rustc-hash",
|
||||
"unic-langid",
|
||||
]
|
||||
|
||||
@@ -4488,7 +4520,7 @@ dependencies = [
|
||||
"indexmap",
|
||||
"log",
|
||||
"num-traits",
|
||||
"rustc-hash 1.999.999",
|
||||
"rustc-hash",
|
||||
"serde",
|
||||
"spirv",
|
||||
"strum",
|
||||
@@ -4917,7 +4949,7 @@ checksum = "d01a5bd0424d00070b0098dd17ebca6f961a959dead1dbcbbbc1d1cd8d3deeba"
|
||||
[[package]]
|
||||
name = "payload-support"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=50c3f77fa264974678ec59e752fe7dc39c29900b#50c3f77fa264974678ec59e752fe7dc39c29900b"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=d773da92641d92930b7308300e9fc2746a05ce6a#d773da92641d92930b7308300e9fc2746a05ce6a"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_derive",
|
||||
@@ -5413,7 +5445,7 @@ checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
|
||||
[[package]]
|
||||
name = "relevancy"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=50c3f77fa264974678ec59e752fe7dc39c29900b#50c3f77fa264974678ec59e752fe7dc39c29900b"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=d773da92641d92930b7308300e9fc2746a05ce6a#d773da92641d92930b7308300e9fc2746a05ce6a"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64 0.21.999",
|
||||
@@ -5438,7 +5470,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "remote_settings"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=50c3f77fa264974678ec59e752fe7dc39c29900b#50c3f77fa264974678ec59e752fe7dc39c29900b"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=d773da92641d92930b7308300e9fc2746a05ce6a#d773da92641d92930b7308300e9fc2746a05ce6a"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"camino",
|
||||
@@ -5483,45 +5515,6 @@ dependencies = [
|
||||
"cache-padded",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rinja"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3dc4940d00595430b3d7d5a01f6222b5e5b51395d1120bdb28d854bb8abb17a5"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"rinja_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rinja_derive"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d9ed0146aef6e2825f1b1515f074510549efba38d71f4554eec32eb36ba18b"
|
||||
dependencies = [
|
||||
"basic-toml",
|
||||
"memchr",
|
||||
"mime",
|
||||
"mime_guess",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rinja_parser",
|
||||
"rustc-hash 2.1.1",
|
||||
"serde",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rinja_parser"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93f9a866e2e00a7a1fb27e46e9e324a6f7c0e7edc4543cae1d38f4e4a100c610"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"nom",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rkv"
|
||||
version = "0.19.0"
|
||||
@@ -5672,16 +5665,9 @@ checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.999.999"
|
||||
dependencies = [
|
||||
"rustc-hash 2.1.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "2.1.1"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
@@ -5767,7 +5753,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "search"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=50c3f77fa264974678ec59e752fe7dc39c29900b#50c3f77fa264974678ec59e752fe7dc39c29900b"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=d773da92641d92930b7308300e9fc2746a05ce6a#d773da92641d92930b7308300e9fc2746a05ce6a"
|
||||
dependencies = [
|
||||
"error-support",
|
||||
"firefox-versioning",
|
||||
@@ -6057,7 +6043,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "sql-support"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=50c3f77fa264974678ec59e752fe7dc39c29900b#50c3f77fa264974678ec59e752fe7dc39c29900b"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=d773da92641d92930b7308300e9fc2746a05ce6a#d773da92641d92930b7308300e9fc2746a05ce6a"
|
||||
dependencies = [
|
||||
"interrupt-support",
|
||||
"lazy_static",
|
||||
@@ -6256,7 +6242,7 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
|
||||
[[package]]
|
||||
name = "suggest"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=50c3f77fa264974678ec59e752fe7dc39c29900b#50c3f77fa264974678ec59e752fe7dc39c29900b"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=d773da92641d92930b7308300e9fc2746a05ce6a#d773da92641d92930b7308300e9fc2746a05ce6a"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
@@ -6308,7 +6294,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "sync-guid"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=50c3f77fa264974678ec59e752fe7dc39c29900b#50c3f77fa264974678ec59e752fe7dc39c29900b"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=d773da92641d92930b7308300e9fc2746a05ce6a#d773da92641d92930b7308300e9fc2746a05ce6a"
|
||||
dependencies = [
|
||||
"base64 0.21.999",
|
||||
"rand",
|
||||
@@ -6319,7 +6305,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "sync15"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=50c3f77fa264974678ec59e752fe7dc39c29900b#50c3f77fa264974678ec59e752fe7dc39c29900b"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=d773da92641d92930b7308300e9fc2746a05ce6a#d773da92641d92930b7308300e9fc2746a05ce6a"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"error-support",
|
||||
@@ -6359,7 +6345,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "tabs"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=50c3f77fa264974678ec59e752fe7dc39c29900b#50c3f77fa264974678ec59e752fe7dc39c29900b"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=d773da92641d92930b7308300e9fc2746a05ce6a#d773da92641d92930b7308300e9fc2746a05ce6a"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"error-support",
|
||||
@@ -6685,7 +6671,7 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6d3364c5e96cb2ad1603037ab253ddd34d7fb72a58bdddf4b7350760fc69a46"
|
||||
dependencies = [
|
||||
"rustc-hash 1.999.999",
|
||||
"rustc-hash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -6703,7 +6689,7 @@ checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
|
||||
[[package]]
|
||||
name = "types"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=50c3f77fa264974678ec59e752fe7dc39c29900b#50c3f77fa264974678ec59e752fe7dc39c29900b"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=d773da92641d92930b7308300e9fc2746a05ce6a#d773da92641d92930b7308300e9fc2746a05ce6a"
|
||||
dependencies = [
|
||||
"rusqlite",
|
||||
"serde",
|
||||
@@ -6786,9 +6772,9 @@ checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
||||
|
||||
[[package]]
|
||||
name = "uniffi"
|
||||
version = "0.29.0"
|
||||
version = "0.28.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba62a57e90f9baed5ad02a71a0870180fa1cc35499093b2d21be2edfb68ec0f7"
|
||||
checksum = "51ce6280c581045879e11b400bae14686a819df22b97171215d15549efa04ddb"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cargo_metadata",
|
||||
@@ -6803,12 +6789,12 @@ name = "uniffi-bindgen-gecko-js"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"askama",
|
||||
"camino",
|
||||
"cargo_metadata",
|
||||
"clap",
|
||||
"extend",
|
||||
"heck",
|
||||
"rinja",
|
||||
"serde",
|
||||
"textwrap",
|
||||
"toml",
|
||||
@@ -6908,11 +6894,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_bindgen"
|
||||
version = "0.29.0"
|
||||
version = "0.28.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2242f35214f1e0e3b47c495d340c69f649f9a9ece3a943a29e275686cc884533"
|
||||
checksum = "5e9f25730c9db2e878521d606f54e921edb719cdd94d735e7f97705d6796d024"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"askama",
|
||||
"camino",
|
||||
"cargo_metadata",
|
||||
"fs-err",
|
||||
@@ -6921,7 +6908,6 @@ dependencies = [
|
||||
"heck",
|
||||
"once_cell",
|
||||
"paste",
|
||||
"rinja",
|
||||
"serde",
|
||||
"textwrap",
|
||||
"toml",
|
||||
@@ -6932,9 +6918,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_build"
|
||||
version = "0.29.0"
|
||||
version = "0.28.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c887a6c9a2857d8dc2ab0c8d578e8aa4978145b4fd65ed44296341e89aebc3cc"
|
||||
checksum = "88dba57ac699bd8ec53d6a352c8dd0e479b33f698c5659831bb1e4ce468c07bd"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"camino",
|
||||
@@ -6942,34 +6928,36 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_core"
|
||||
version = "0.29.0"
|
||||
name = "uniffi_checksum_derive"
|
||||
version = "0.28.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cad9fbdeb7ae4daf8d0f7704a3b638c37018eb16bb701e30fa17a2dd3e2d39c1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
"once_cell",
|
||||
"paste",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_internal_macros"
|
||||
version = "0.29.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22a9dba1d78b9ce429439891089c223478043d52a1c3176a0fcea2b5573a7fcf"
|
||||
checksum = "d2c801f0f05b06df456a2da4c41b9c2c4fdccc6b9916643c6c67275c4c9e4d07"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_macros"
|
||||
version = "0.29.0"
|
||||
name = "uniffi_core"
|
||||
version = "0.28.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78dd5f8eefba5898b901086f5e7916da67b9a5286a01cc44e910cd75fa37c630"
|
||||
checksum = "61049e4db6212d0ede80982adf0e1d6fa224e6118387324c5cfbe3083dfb2252"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
"log",
|
||||
"once_cell",
|
||||
"paste",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_macros"
|
||||
version = "0.28.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b40fd2249e0c5dcbd2bfa3c263db1ec981f7273dca7f4132bf06a272359a586c"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"camino",
|
||||
"fs-err",
|
||||
"once_cell",
|
||||
@@ -6983,20 +6971,21 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_meta"
|
||||
version = "0.29.0"
|
||||
version = "0.28.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d5965b1d4ffacef1eaa72fef9c00d2491641e87ad910f6c5859b9c503ddb16a"
|
||||
checksum = "c9ad57039b4fafdbf77428d74fff40e0908e5a1731e023c19cfe538f6d4a8ed6"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
"siphasher",
|
||||
"uniffi_internal_macros",
|
||||
"uniffi_checksum_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_testing"
|
||||
version = "0.29.0"
|
||||
version = "0.28.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43b0f35750a3e1836f10f26e4eceba688748b8a1e94a6ee251c976099d984d4f"
|
||||
checksum = "21fa171d4d258dc51bbd01893cc9608c1b62273d2f9ea55fb64f639e77824567"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"camino",
|
||||
@@ -7007,13 +6996,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_udl"
|
||||
version = "0.29.0"
|
||||
version = "0.28.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "279b82bac9a382c796a0d210bb8354a0b813499b28aa1de046c85d78ca389805"
|
||||
checksum = "f52299e247419e7e2934bef2f94d7cccb0e6566f3248b1d48b160d8f369a2668"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"textwrap",
|
||||
"uniffi_meta",
|
||||
"uniffi_testing",
|
||||
"weedle2",
|
||||
]
|
||||
|
||||
@@ -7079,7 +7069,7 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
[[package]]
|
||||
name = "viaduct"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=50c3f77fa264974678ec59e752fe7dc39c29900b#50c3f77fa264974678ec59e752fe7dc39c29900b"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=d773da92641d92930b7308300e9fc2746a05ce6a#d773da92641d92930b7308300e9fc2746a05ce6a"
|
||||
dependencies = [
|
||||
"ffi-support",
|
||||
"log",
|
||||
@@ -7249,7 +7239,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "webext-storage"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=50c3f77fa264974678ec59e752fe7dc39c29900b#50c3f77fa264974678ec59e752fe7dc39c29900b"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=d773da92641d92930b7308300e9fc2746a05ce6a#d773da92641d92930b7308300e9fc2746a05ce6a"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"error-support",
|
||||
@@ -7403,7 +7393,7 @@ dependencies = [
|
||||
"parking_lot",
|
||||
"profiling",
|
||||
"ron",
|
||||
"rustc-hash 1.999.999",
|
||||
"rustc-hash",
|
||||
"serde",
|
||||
"smallvec",
|
||||
"thiserror 2.0.9",
|
||||
|
||||
27
Cargo.toml
27
Cargo.toml
@@ -61,12 +61,12 @@ rust-version = "1.82.0"
|
||||
|
||||
[workspace.dependencies]
|
||||
# Shared across multiple UniFFI consumers.
|
||||
uniffi = "0.29.0"
|
||||
uniffi_bindgen = "0.29.0"
|
||||
uniffi = "0.28.2"
|
||||
uniffi_bindgen = "0.28.2"
|
||||
# Shared across multiple application-services consumers.
|
||||
rusqlite = "0.31.0"
|
||||
# Shared across multiple glean consumers.
|
||||
glean = "=64.0.0"
|
||||
glean = "=63.1.0"
|
||||
|
||||
# Explicitly specify what our profiles use. The opt-level setting here is
|
||||
# a total fiction; see the setup of MOZ_RUST_DEFAULT_FLAGS for what the
|
||||
@@ -176,9 +176,6 @@ goblin = { path = "build/rust/goblin" }
|
||||
# Implement getrandom 0.2 in terms of 0.3
|
||||
getrandom = { path = "build/rust/getrandom" }
|
||||
|
||||
# Patch rustc-hash 1.1.0 to 2.1.1
|
||||
rustc-hash = { path = "build/rust/rustc-hash" }
|
||||
|
||||
# Patch memoffset from 0.8.0 to 0.9.0 since it's compatible and it avoids duplication
|
||||
memoffset = { path = "build/rust/memoffset" }
|
||||
|
||||
@@ -244,14 +241,14 @@ malloc_size_of_derive = { path = "xpcom/rust/malloc_size_of_derive" }
|
||||
objc = { git = "https://github.com/glandium/rust-objc", rev = "4de89f5aa9851ceca4d40e7ac1e2759410c04324" }
|
||||
|
||||
# application-services overrides to make updating them all simpler.
|
||||
interrupt-support = { git = "https://github.com/mozilla/application-services", rev = "50c3f77fa264974678ec59e752fe7dc39c29900b" }
|
||||
relevancy = { git = "https://github.com/mozilla/application-services", rev = "50c3f77fa264974678ec59e752fe7dc39c29900b" }
|
||||
search = { git = "https://github.com/mozilla/application-services", rev = "50c3f77fa264974678ec59e752fe7dc39c29900b" }
|
||||
sql-support = { git = "https://github.com/mozilla/application-services", rev = "50c3f77fa264974678ec59e752fe7dc39c29900b" }
|
||||
suggest = { git = "https://github.com/mozilla/application-services", rev = "50c3f77fa264974678ec59e752fe7dc39c29900b" }
|
||||
sync15 = { git = "https://github.com/mozilla/application-services", rev = "50c3f77fa264974678ec59e752fe7dc39c29900b" }
|
||||
tabs = { git = "https://github.com/mozilla/application-services", rev = "50c3f77fa264974678ec59e752fe7dc39c29900b" }
|
||||
viaduct = { git = "https://github.com/mozilla/application-services", rev = "50c3f77fa264974678ec59e752fe7dc39c29900b" }
|
||||
webext-storage = { git = "https://github.com/mozilla/application-services", rev = "50c3f77fa264974678ec59e752fe7dc39c29900b" }
|
||||
interrupt-support = { git = "https://github.com/mozilla/application-services", rev = "d773da92641d92930b7308300e9fc2746a05ce6a" }
|
||||
relevancy = { git = "https://github.com/mozilla/application-services", rev = "d773da92641d92930b7308300e9fc2746a05ce6a" }
|
||||
search = { git = "https://github.com/mozilla/application-services", rev = "d773da92641d92930b7308300e9fc2746a05ce6a" }
|
||||
sql-support = { git = "https://github.com/mozilla/application-services", rev = "d773da92641d92930b7308300e9fc2746a05ce6a" }
|
||||
suggest = { git = "https://github.com/mozilla/application-services", rev = "d773da92641d92930b7308300e9fc2746a05ce6a" }
|
||||
sync15 = { git = "https://github.com/mozilla/application-services", rev = "d773da92641d92930b7308300e9fc2746a05ce6a" }
|
||||
tabs = { git = "https://github.com/mozilla/application-services", rev = "d773da92641d92930b7308300e9fc2746a05ce6a" }
|
||||
viaduct = { git = "https://github.com/mozilla/application-services", rev = "d773da92641d92930b7308300e9fc2746a05ce6a" }
|
||||
webext-storage = { git = "https://github.com/mozilla/application-services", rev = "d773da92641d92930b7308300e9fc2746a05ce6a" }
|
||||
|
||||
allocator-api2 = { path = "third_party/rust/allocator-api2" }
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
[package]
|
||||
name = "rustc-hash"
|
||||
version = "1.999.999"
|
||||
edition = "2018"
|
||||
license = "Apache-2.0 OR MIT"
|
||||
|
||||
[lib]
|
||||
path = "lib.rs"
|
||||
|
||||
[dependencies.rustc-hash]
|
||||
version = "2.1.1"
|
||||
default-features = false
|
||||
|
||||
[features]
|
||||
default = ["rustc-hash/default"]
|
||||
std = ["rustc-hash/std"]
|
||||
rand = ["rustc-hash/rand"]
|
||||
@@ -1,11 +0,0 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub use rustc_hash::*;
|
||||
202
gfx/wr/Cargo.lock
generated
202
gfx/wr/Cargo.lock
generated
@@ -87,6 +87,38 @@ dependencies = [
|
||||
"term",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "askama"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47cbc3cf73fa8d9833727bbee4835ba5c421a0d65b72daf9a7b5d0e0f9cfb57e"
|
||||
dependencies = [
|
||||
"askama_derive",
|
||||
"askama_escape",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "askama_derive"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c22fbe0413545c098358e56966ff22cdd039e10215ae213cfbd65032b119fc94"
|
||||
dependencies = [
|
||||
"basic-toml",
|
||||
"mime",
|
||||
"mime_guess",
|
||||
"nom 7.1.1",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"syn 2.0.25",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "askama_escape"
|
||||
version = "0.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341"
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
@@ -149,7 +181,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"rustc-hash 1.1.0",
|
||||
"rustc-hash",
|
||||
"shlex",
|
||||
"syn 2.0.25",
|
||||
"which",
|
||||
@@ -253,6 +285,32 @@ name = "camino"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "869119e97797867fd90f5e22af7d0bd274bd4635ebb9eb68c04f3f513ae6c412"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cargo-platform"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cbdb825da8a5df079a43676dbe042702f1707b1109f713a01420fbb4cc71fa27"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cargo_metadata"
|
||||
version = "0.15.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "982a0cf6a99c350d7246035613882e376d58cebe571785abc5da4f648d53ac0a"
|
||||
dependencies = [
|
||||
"camino",
|
||||
"cargo-platform",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cbitset"
|
||||
@@ -982,9 +1040,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "glean"
|
||||
version = "64.0.0"
|
||||
version = "63.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba92338cfd9fb34b00c02c6da8e22936b41835eb02ab5462d3d88cc4b6249c35"
|
||||
checksum = "e2afa6754943cac5243099efd0d26e89cc8e06f1585776ba14ab0c6ee99e1f71"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"glean-core",
|
||||
@@ -996,9 +1054,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "glean-core"
|
||||
version = "64.0.0"
|
||||
version = "63.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92a2cbf41fbb9996b14fc1721b8bd06e669589de05e6efc20a24bab14285623a"
|
||||
checksum = "53cd53bb7a3b89b17d3989e95dd808b137ff47c504d1d19f14cb0d820cc2f42e"
|
||||
dependencies = [
|
||||
"android_logger",
|
||||
"bincode",
|
||||
@@ -1311,9 +1369,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.15"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
||||
checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d"
|
||||
|
||||
[[package]]
|
||||
name = "jni-sys"
|
||||
@@ -2270,45 +2328,6 @@ version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
||||
|
||||
[[package]]
|
||||
name = "rinja"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3dc4940d00595430b3d7d5a01f6222b5e5b51395d1120bdb28d854bb8abb17a5"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"rinja_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rinja_derive"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d9ed0146aef6e2825f1b1515f074510549efba38d71f4554eec32eb36ba18b"
|
||||
dependencies = [
|
||||
"basic-toml",
|
||||
"memchr",
|
||||
"mime",
|
||||
"mime_guess",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rinja_parser",
|
||||
"rustc-hash 2.1.1",
|
||||
"serde",
|
||||
"syn 2.0.25",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rinja_parser"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93f9a866e2e00a7a1fb27e46e9e324a6f7c0e7edc4543cae1d38f4e4a100c610"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"nom 7.1.1",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rkv"
|
||||
version = "0.19.0"
|
||||
@@ -2351,7 +2370,7 @@ dependencies = [
|
||||
"countme",
|
||||
"hashbrown 0.12.3",
|
||||
"memoffset",
|
||||
"rustc-hash 1.1.0",
|
||||
"rustc-hash",
|
||||
"text-size",
|
||||
]
|
||||
|
||||
@@ -2361,12 +2380,6 @@ version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.38"
|
||||
@@ -2438,6 +2451,9 @@ name = "semver"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2333e6df6d6598f2b1974829f853c2b4c5f4a6e503c10af918081aa6f8564e1"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
@@ -2828,9 +2844,9 @@ checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
|
||||
|
||||
[[package]]
|
||||
name = "uniffi"
|
||||
version = "0.29.0"
|
||||
version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba62a57e90f9baed5ad02a71a0870180fa1cc35499093b2d21be2edfb68ec0f7"
|
||||
checksum = "2db87def739fe4183947f8419d572d1849a4a09355eba4e988a2105cfd0ac6a7"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"uniffi_build",
|
||||
@@ -2840,11 +2856,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_bindgen"
|
||||
version = "0.29.0"
|
||||
version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2242f35214f1e0e3b47c495d340c69f649f9a9ece3a943a29e275686cc884533"
|
||||
checksum = "7a112599c9556d1581e4a3d72019a74c2c3e122cc27f4af12577a429c4d5e614"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"askama",
|
||||
"camino",
|
||||
"fs-err",
|
||||
"glob",
|
||||
@@ -2852,7 +2869,6 @@ dependencies = [
|
||||
"heck",
|
||||
"once_cell",
|
||||
"paste",
|
||||
"rinja",
|
||||
"serde",
|
||||
"textwrap 0.16.1",
|
||||
"toml",
|
||||
@@ -2862,9 +2878,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_build"
|
||||
version = "0.29.0"
|
||||
version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c887a6c9a2857d8dc2ab0c8d578e8aa4978145b4fd65ed44296341e89aebc3cc"
|
||||
checksum = "e2b12684401d2a8508ca9c72a95bbc45906417e42fc80942abaf033bbf01aa33"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"camino",
|
||||
@@ -2872,34 +2888,37 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_core"
|
||||
version = "0.29.0"
|
||||
name = "uniffi_checksum_derive"
|
||||
version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cad9fbdeb7ae4daf8d0f7704a3b638c37018eb16bb701e30fa17a2dd3e2d39c1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
"once_cell",
|
||||
"paste",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_internal_macros"
|
||||
version = "0.29.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22a9dba1d78b9ce429439891089c223478043d52a1c3176a0fcea2b5573a7fcf"
|
||||
checksum = "a22dbe67c1c957ac6e7611bdf605a6218aa86b0eebeb8be58b70ae85ad7d73dc"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.25",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_macros"
|
||||
version = "0.29.0"
|
||||
name = "uniffi_core"
|
||||
version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78dd5f8eefba5898b901086f5e7916da67b9a5286a01cc44e910cd75fa37c630"
|
||||
checksum = "5a0c35aaad30e3a9e6d4fe34e358d64dbc92ee09045b48591b05fc9f12e0905b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
"camino",
|
||||
"log",
|
||||
"once_cell",
|
||||
"paste",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_macros"
|
||||
version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db66474c5c61b0f7afc3b4995fecf9b72b340daa5ca0ef3da7778d75eb5482ea"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"camino",
|
||||
"fs-err",
|
||||
"once_cell",
|
||||
@@ -2913,24 +2932,39 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_meta"
|
||||
version = "0.29.0"
|
||||
version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d5965b1d4ffacef1eaa72fef9c00d2491641e87ad910f6c5859b9c503ddb16a"
|
||||
checksum = "d898893f102e0e39b8bcb7e3d2188f4156ba280db32db9e8af1f122d057e9526"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
"siphasher",
|
||||
"uniffi_internal_macros",
|
||||
"uniffi_checksum_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_testing"
|
||||
version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c6aa4f0cf9d12172d84fc00a35a6c1f3522b526daad05ae739f709f6941b9b6"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"camino",
|
||||
"cargo_metadata",
|
||||
"fs-err",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_udl"
|
||||
version = "0.29.0"
|
||||
version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "279b82bac9a382c796a0d210bb8354a0b813499b28aa1de046c85d78ca389805"
|
||||
checksum = "6b044e9c519e0bb51e516ab6f6d8f4f4dcf900ce30d5ad07c03f924e2824f28e"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"textwrap 0.16.1",
|
||||
"uniffi_meta",
|
||||
"uniffi_testing",
|
||||
"weedle2",
|
||||
]
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ members = [
|
||||
resolver = "2"
|
||||
|
||||
[workspace.dependencies]
|
||||
glean = "=64.0.0"
|
||||
glean = "=63.1.0"
|
||||
|
||||
[profile.release]
|
||||
debug = true
|
||||
|
||||
@@ -28,8 +28,6 @@ packages = [
|
||||
"parking_lot_core",
|
||||
"rand",
|
||||
"rand_core",
|
||||
# rinja (dependency of uniffi) requires 2.1, rowan requires 1.1
|
||||
"rustc-hash",
|
||||
# transition to syn 2 is underway.
|
||||
"syn",
|
||||
"synstructure",
|
||||
|
||||
@@ -4,7 +4,7 @@ android-gradle-plugin = "8.9.1" # Keep lint version in sync
|
||||
lint = "31.9.1"
|
||||
|
||||
python-envs-plugin = "0.0.31"
|
||||
mozilla-glean = "64.0.0"
|
||||
mozilla-glean = "63.1.0"
|
||||
maven-ant-tasks = "2.1.3"
|
||||
jacoco = "0.8.12"
|
||||
okhttp = "4.12.0"
|
||||
|
||||
@@ -11,11 +11,8 @@ import mozilla.components.concept.fetch.Header
|
||||
import mozilla.components.concept.fetch.Request
|
||||
import mozilla.components.concept.fetch.toMutableHeaders
|
||||
import mozilla.components.support.base.log.logger.Logger
|
||||
import mozilla.telemetry.glean.net.CapablePingUploadRequest
|
||||
import mozilla.telemetry.glean.net.HeadersList
|
||||
import mozilla.telemetry.glean.net.HttpStatus
|
||||
import mozilla.telemetry.glean.net.Incapable
|
||||
import mozilla.telemetry.glean.net.PingUploadRequest
|
||||
import mozilla.telemetry.glean.net.RecoverableFailure
|
||||
import mozilla.telemetry.glean.net.UploadResult
|
||||
import java.io.IOException
|
||||
@@ -67,12 +64,8 @@ class ConceptFetchHttpUploader(
|
||||
* or faced an unrecoverable error), false if there was a recoverable
|
||||
* error callers can deal with.
|
||||
*/
|
||||
override fun upload(request: CapablePingUploadRequest): UploadResult {
|
||||
val req: PingUploadRequest? = request.capable({ capabilities: List<String> -> capabilities.size == 0 })
|
||||
if (req == null) {
|
||||
return Incapable(0)
|
||||
}
|
||||
val request = buildRequest(req)
|
||||
override fun upload(url: String, data: ByteArray, headers: HeadersList): UploadResult {
|
||||
val request = buildRequest(url, data, headers)
|
||||
|
||||
return try {
|
||||
performUpload(client.value, request)
|
||||
@@ -83,11 +76,15 @@ class ConceptFetchHttpUploader(
|
||||
}
|
||||
|
||||
@VisibleForTesting(otherwise = PRIVATE)
|
||||
internal fun buildRequest(request: PingUploadRequest): Request {
|
||||
val conceptHeaders = request.headers.map { (name, value) -> Header(name, value) }.toMutableHeaders()
|
||||
internal fun buildRequest(
|
||||
url: String,
|
||||
data: ByteArray,
|
||||
headers: HeadersList,
|
||||
): Request {
|
||||
val conceptHeaders = headers.map { (name, value) -> Header(name, value) }.toMutableHeaders()
|
||||
|
||||
return Request(
|
||||
url = request.url,
|
||||
url = url,
|
||||
method = Request.Method.POST,
|
||||
connectTimeout = Pair(DEFAULT_CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS),
|
||||
readTimeout = Pair(DEFAULT_READ_TIMEOUT, TimeUnit.MILLISECONDS),
|
||||
@@ -96,7 +93,7 @@ class ConceptFetchHttpUploader(
|
||||
// offer a better API to do that, so we nuke all cookies going to our telemetry
|
||||
// endpoint.
|
||||
cookiePolicy = Request.CookiePolicy.OMIT,
|
||||
body = Request.Body(request.data.inputStream()),
|
||||
body = Request.Body(data.inputStream()),
|
||||
private = usePrivateRequest,
|
||||
conservative = true,
|
||||
)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// These lines are generated by android-components/automation/application-services-nightly-bump.py
|
||||
val VERSION = "138.20250325204448"
|
||||
val VERSION = "138.20250325050356"
|
||||
val CHANNEL = ApplicationServicesChannel.NIGHTLY
|
||||
|
||||
object ApplicationServicesConfig {
|
||||
|
||||
@@ -31,11 +31,11 @@ origin:
|
||||
|
||||
# Human-readable identifier for this version/release
|
||||
# Generally "version NNN", "tag SSS", "bookmark SSS"
|
||||
release: 8afded70f1c057fc8943108f98964efb61a30afb (2025-03-25T20:44:48).
|
||||
release: 093c4f261a91b2a7d6f52da4f79bef19f61456fb (2025-03-25T05:03:56).
|
||||
|
||||
# Revision to pull in
|
||||
# Must be a long or short commit SHA (long preferred)
|
||||
revision: 8afded70f1c057fc8943108f98964efb61a30afb
|
||||
revision: 093c4f261a91b2a7d6f52da4f79bef19f61456fb
|
||||
|
||||
# The package's license, where possible using the mnemonic from
|
||||
# https://spdx.org/licenses/
|
||||
|
||||
@@ -104,7 +104,7 @@ vendored:third_party/python/wheel
|
||||
vendored:third_party/python/zipp
|
||||
# glean-sdk may not be installable if a wheel isn't available
|
||||
# and it has to be built from source.
|
||||
pypi-optional:glean-sdk==64.0.0:telemetry will not be collected
|
||||
pypi-optional:glean-sdk==63.1.0:telemetry will not be collected
|
||||
# Mach gracefully handles the case where `psutil` is unavailable.
|
||||
# We aren't (yet) able to pin packages in automation, so we have to
|
||||
# support down to the oldest locally-installed version (5.4.2).
|
||||
|
||||
@@ -531,13 +531,6 @@ start = "2023-06-21"
|
||||
end = "2026-02-01"
|
||||
notes = "Maintained by the Glean and Application Services teams"
|
||||
|
||||
[[wildcard-audits.uniffi_internal_macros]]
|
||||
who = "Jan-Erik Rediger <jrediger@mozilla.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
user-id = 111105
|
||||
start = "2025-03-18"
|
||||
end = "2026-03-25"
|
||||
|
||||
[[wildcard-audits.uniffi_macros]]
|
||||
who = "Ben Dean-Kawamura <bdk@mozilla.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
@@ -6311,6 +6304,12 @@ non-1-byte-aligned type, however right now that is not the case
|
||||
(submitted https://github.com/zip-rs/zip2/issues/198).
|
||||
"""
|
||||
|
||||
[[audits.zlib-rs]]
|
||||
who = "Mike Hommey <mh+mozilla@glandium.org>"
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "0.2.1 -> 0.2.1@git:4aa430ccb77537d0d60dab8db993ca51bb1194c5"
|
||||
importable = false
|
||||
|
||||
[[trusted.aho-corasick]]
|
||||
criteria = "safe-to-deploy"
|
||||
user-id = 189 # Andrew Gallant (BurntSushi)
|
||||
|
||||
@@ -297,6 +297,14 @@ criteria = "safe-to-deploy"
|
||||
version = "0.2.0"
|
||||
criteria = "safe-to-deploy"
|
||||
|
||||
[[exemptions.askama_derive]]
|
||||
version = "0.11.2"
|
||||
criteria = "safe-to-deploy"
|
||||
|
||||
[[exemptions.askama_escape]]
|
||||
version = "0.10.3"
|
||||
criteria = "safe-to-deploy"
|
||||
|
||||
[[exemptions.async-task]]
|
||||
version = "4.0.3"
|
||||
criteria = "safe-to-deploy"
|
||||
@@ -518,6 +526,10 @@ criteria = "safe-to-deploy"
|
||||
version = "0.10.3"
|
||||
criteria = "safe-to-deploy"
|
||||
|
||||
[[exemptions.khronos-egl]]
|
||||
version = "4.1.0"
|
||||
criteria = "safe-to-deploy"
|
||||
|
||||
[[exemptions.khronos_api]]
|
||||
version = "3.1.0"
|
||||
criteria = "safe-to-deploy"
|
||||
@@ -630,6 +642,10 @@ criteria = "safe-to-deploy"
|
||||
version = "1.2.3"
|
||||
criteria = "safe-to-deploy"
|
||||
|
||||
[[exemptions.rand]]
|
||||
version = "0.8.5"
|
||||
criteria = "safe-to-deploy"
|
||||
|
||||
[[exemptions.remove_dir_all]]
|
||||
version = "0.5.3"
|
||||
criteria = "safe-to-deploy"
|
||||
|
||||
@@ -258,15 +258,15 @@ user-login = "jrmuizel"
|
||||
user-name = "Jeff Muizelaar"
|
||||
|
||||
[[publisher.glean]]
|
||||
version = "64.0.0"
|
||||
when = "2025-03-18"
|
||||
version = "63.1.0"
|
||||
when = "2025-01-30"
|
||||
user-id = 48
|
||||
user-login = "badboy"
|
||||
user-name = "Jan-Erik Rediger"
|
||||
|
||||
[[publisher.glean-core]]
|
||||
version = "64.0.0"
|
||||
when = "2025-03-18"
|
||||
version = "63.1.0"
|
||||
when = "2025-01-30"
|
||||
user-id = 48
|
||||
user-login = "badboy"
|
||||
user-name = "Jan-Erik Rediger"
|
||||
@@ -335,8 +335,8 @@ user-login = "carllerche"
|
||||
user-name = "Carl Lerche"
|
||||
|
||||
[[publisher.itoa]]
|
||||
version = "1.0.11"
|
||||
when = "2024-03-26"
|
||||
version = "1.0.5"
|
||||
when = "2022-12-17"
|
||||
user-id = 3618
|
||||
user-login = "dtolnay"
|
||||
user-name = "David Tolnay"
|
||||
@@ -711,56 +711,56 @@ user-login = "Manishearth"
|
||||
user-name = "Manish Goregaokar"
|
||||
|
||||
[[publisher.uniffi]]
|
||||
version = "0.29.0"
|
||||
when = "2025-02-06"
|
||||
version = "0.28.2"
|
||||
when = "2024-10-08"
|
||||
user-id = 127697
|
||||
user-login = "bendk"
|
||||
|
||||
[[publisher.uniffi_bindgen]]
|
||||
version = "0.29.0"
|
||||
when = "2025-02-06"
|
||||
version = "0.28.2"
|
||||
when = "2024-10-08"
|
||||
user-id = 127697
|
||||
user-login = "bendk"
|
||||
|
||||
[[publisher.uniffi_build]]
|
||||
version = "0.29.0"
|
||||
when = "2025-02-06"
|
||||
version = "0.28.2"
|
||||
when = "2024-10-08"
|
||||
user-id = 127697
|
||||
user-login = "bendk"
|
||||
|
||||
[[publisher.uniffi_checksum_derive]]
|
||||
version = "0.28.2"
|
||||
when = "2024-10-08"
|
||||
user-id = 127697
|
||||
user-login = "bendk"
|
||||
|
||||
[[publisher.uniffi_core]]
|
||||
version = "0.29.0"
|
||||
when = "2025-02-06"
|
||||
user-id = 127697
|
||||
user-login = "bendk"
|
||||
|
||||
[[publisher.uniffi_internal_macros]]
|
||||
version = "0.29.0"
|
||||
when = "2025-02-06"
|
||||
version = "0.28.2"
|
||||
when = "2024-10-08"
|
||||
user-id = 127697
|
||||
user-login = "bendk"
|
||||
|
||||
[[publisher.uniffi_macros]]
|
||||
version = "0.29.0"
|
||||
when = "2025-02-06"
|
||||
version = "0.28.2"
|
||||
when = "2024-10-08"
|
||||
user-id = 127697
|
||||
user-login = "bendk"
|
||||
|
||||
[[publisher.uniffi_meta]]
|
||||
version = "0.29.0"
|
||||
when = "2025-02-06"
|
||||
version = "0.28.2"
|
||||
when = "2024-10-08"
|
||||
user-id = 127697
|
||||
user-login = "bendk"
|
||||
|
||||
[[publisher.uniffi_testing]]
|
||||
version = "0.29.0"
|
||||
when = "2025-02-06"
|
||||
version = "0.28.2"
|
||||
when = "2024-10-08"
|
||||
user-id = 127697
|
||||
user-login = "bendk"
|
||||
|
||||
[[publisher.uniffi_udl]]
|
||||
version = "0.29.0"
|
||||
when = "2025-02-06"
|
||||
version = "0.28.2"
|
||||
when = "2024-10-08"
|
||||
user-id = 127697
|
||||
user-login = "bendk"
|
||||
|
||||
@@ -1203,11 +1203,6 @@ crate is broadly used throughout the ecosystem and does not contain anything
|
||||
suspicious.
|
||||
"""
|
||||
|
||||
[[audits.bytecode-alliance.audits.itoa]]
|
||||
who = "Dan Gohman <dev@sunfishcode.online>"
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "1.0.11 -> 1.0.14"
|
||||
|
||||
[[audits.bytecode-alliance.audits.jobserver]]
|
||||
who = "Alex Crichton <alex@alexcrichton.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
@@ -1550,13 +1545,6 @@ criteria = "safe-to-run"
|
||||
version = "0.14.20"
|
||||
aggregated-from = "https://chromium.googlesource.com/chromiumos/third_party/rust_crates/+/refs/heads/main/cargo-vet/audits.toml?format=TEXT"
|
||||
|
||||
[[audits.google.audits.itoa]]
|
||||
who = "Daniel Cheng <dcheng@chromium.org>"
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "1.0.14 -> 1.0.15"
|
||||
notes = "Only minor rustdoc changes."
|
||||
aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT"
|
||||
|
||||
[[audits.google.audits.nom]]
|
||||
who = "danakj@chromium.org"
|
||||
criteria = "safe-to-deploy"
|
||||
@@ -1611,15 +1599,6 @@ Config-related changes in `test_size.rs`.
|
||||
"""
|
||||
aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT"
|
||||
|
||||
[[audits.google.audits.rand]]
|
||||
who = "Lukasz Anforowicz <lukasza@chromium.org>"
|
||||
criteria = "safe-to-deploy"
|
||||
version = "0.8.5"
|
||||
notes = """
|
||||
For more detailed unsafe review notes please see https://crrev.com/c/6362797
|
||||
"""
|
||||
aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT"
|
||||
|
||||
[[audits.google.audits.rustversion]]
|
||||
who = "Lukasz Anforowicz <lukasza@chromium.org>"
|
||||
criteria = "safe-to-deploy"
|
||||
@@ -1971,14 +1950,6 @@ who = "Ameer Ghani <inahga@divviup.org>"
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "0.4.1 -> 0.4.2"
|
||||
|
||||
[[audits.mozilla.wildcard-audits.uniffi_internal_macros]]
|
||||
who = "Jan-Erik Rediger <jrediger@mozilla.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
user-id = 127697 # bendk
|
||||
start = "2025-02-06"
|
||||
end = "2026-03-14"
|
||||
aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml"
|
||||
|
||||
[[audits.mozilla.wildcard-audits.weedle2]]
|
||||
who = "Jan-Erik Rediger <jrediger@mozilla.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
@@ -1997,6 +1968,20 @@ end = "2025-08-05"
|
||||
notes = "Maintained by me"
|
||||
aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml"
|
||||
|
||||
[[audits.mozilla.audits.askama]]
|
||||
who = "Jan-Erik Rediger <jrediger@mozilla.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "0.11.1 -> 0.12.0"
|
||||
notes = "No new unsafe usage, mostly dependency updates and smaller API changes"
|
||||
aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml"
|
||||
|
||||
[[audits.mozilla.audits.askama_derive]]
|
||||
who = "Jan-Erik Rediger <jrediger@mozilla.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "0.11.2 -> 0.12.1"
|
||||
notes = "Dependency updates, a new toml dependency and some API changes. No unsafe use."
|
||||
aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml"
|
||||
|
||||
[[audits.mozilla.audits.basic-toml]]
|
||||
who = "Jan-Erik Rediger <jrediger@mozilla.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Metadata-Version: 2.1
|
||||
Name: glean_parser
|
||||
Version: 17.0.1
|
||||
Version: 16.2.0
|
||||
Summary: Parser tools for Mozilla's Glean telemetry
|
||||
Home-page: https://github.com/mozilla/glean_parser
|
||||
Author: The Glean Team
|
||||
@@ -79,14 +79,6 @@ $ glean_parser check < ping.json
|
||||
|
||||
## Unreleased
|
||||
|
||||
## 17.0.1
|
||||
|
||||
- BUGFIX: Fix missing `ping_arg` "`uploader_capabilities`" in util.py ([#786](https://github.com/mozilla/glean_parser/pull/786))
|
||||
|
||||
## 17.0.0
|
||||
|
||||
- BREAKING CHANGE: Support `uploader_capabilities` for pings ([bug 1920732](https://bugzilla.mozilla.org/show_bug.cgi?id=1920732))
|
||||
|
||||
## 16.2.0
|
||||
|
||||
- New lint: error when there are metrics whose names are too similar ([bug 1934099](https://bugzilla.mozilla.org/show_bug.cgi?id=1934099))
|
||||
@@ -10,7 +10,7 @@ glean_parser/lint.py,sha256=ktdkR2GjR0wuR4IpLTiZ-q17vI4dk_Nebp4XU3pqzsk,21103
|
||||
glean_parser/markdown.py,sha256=GkCr1CrV6mnRQseT6FO1-JJ7Eup8X3lxUfRMBTxXpe4,9066
|
||||
glean_parser/metrics.py,sha256=3_ERPI63CsH_QvXVKNBVKIQTv4KWir2SfSbtn6J8a9Q,15842
|
||||
glean_parser/parser.py,sha256=3bJwUGYhnzIHYJ7UBdO63Oi0_n1_Twvr2IOUUe_koME,18132
|
||||
glean_parser/pings.py,sha256=l4hKmnKigS46vlHFI4aWueKVHcZQL36QfhK0VC8OiFA,3924
|
||||
glean_parser/pings.py,sha256=xUgAunjluLbdLtcSQiUL6HDO5aLYM75MAoIT9H8-lOY,3729
|
||||
glean_parser/python_server.py,sha256=ERpYcbSwF19xKFagxX0mZAvlR1y6D7Ah5DSvW8LipCY,4791
|
||||
glean_parser/ruby_server.py,sha256=e5lkfcLQAUMUBQDCjqNU82LkdUzT5x-G6HOnsUInbsU,5190
|
||||
glean_parser/rust.py,sha256=u1IeluyxFj6NrZZrBQwwa0nWz0TABv93lYxVBx0aN3I,7334
|
||||
@@ -19,12 +19,12 @@ glean_parser/swift.py,sha256=paUzF6tItdktFwIQYCKsYpqXfn8zxR2coU_jMYrmwlc,8957
|
||||
glean_parser/tags.py,sha256=bemKYvcbMO4JrghiNSe-A4BNNDtx_FlUPkgrPPJy84Y,1391
|
||||
glean_parser/translate.py,sha256=itObn41X63koLYjdppLiywIFzPWDvPEx7C13efWpDSE,8444
|
||||
glean_parser/translation_options.py,sha256=Lxzr6G7MP0tC_ZYlZXftS4j0SLiqO-5mGVTEc7ggXis,2037
|
||||
glean_parser/util.py,sha256=yTx_-Q8w8rNNSZ_xbno0B90WR7pZZptG2bUWU0sCHZk,16580
|
||||
glean_parser/util.py,sha256=YigUFMhzbXucNx3_bU-SAFWSnnyKS73pQWMBqxRGNn8,16551
|
||||
glean_parser/validate_ping.py,sha256=0TNvILH6dtzJDys3W8Kqorw6kk03me73OCUDtpoHcXU,2118
|
||||
glean_parser/schemas/metrics.1-0-0.schema.yaml,sha256=cND3cvi6iBfPUVmtfIBQfGJV9AALpbvN7nu8E33_J-o,19566
|
||||
glean_parser/schemas/metrics.2-0-0.schema.yaml,sha256=ieFMxezBuySCvUorx8eGqXRUcoeTql4Z9FxkbkG9XFQ,26715
|
||||
glean_parser/schemas/pings.1-0-0.schema.yaml,sha256=hwCnsKpEysmrmVp-QHGBArEkVY3vaU1rVsxlTwhAzws,4315
|
||||
glean_parser/schemas/pings.2-0-0.schema.yaml,sha256=FQBsEt8Eg_ypBUnhJ1THZWXIgtuiYfyXcp_J9pGJUnE,7001
|
||||
glean_parser/schemas/pings.2-0-0.schema.yaml,sha256=5k_OKfNkxHed4j1kMFGkxW1yDpvkqst-Vogig_W_JJU,6420
|
||||
glean_parser/schemas/tags.1-0-0.schema.yaml,sha256=OGXIJlvvVW1vaqB_NVZnwKeZ-sLlfH57vjBSHbj6DNI,1231
|
||||
glean_parser/templates/data_review.jinja2,sha256=jeYU29T1zLSyu9fKBBFu5BFPfIw8_hmOUXw8RXhRXK8,3287
|
||||
glean_parser/templates/go_server.jinja2,sha256=t9ZS5AF5JwoVExkSxDoRQdBoTQv1bchJ7oTRB9eP5FI,9241
|
||||
@@ -37,13 +37,13 @@ glean_parser/templates/markdown.jinja2,sha256=vAHHGGm28HRDPd3zO_wQMAUZIuxE9uQ7hl
|
||||
glean_parser/templates/python_server.jinja2,sha256=gu2C1rkn760IqBCG2SWaK7o32T1ify94wDEsudLPUg8,7260
|
||||
glean_parser/templates/qmldir.jinja2,sha256=m6IGsp-tgTiOfQ7VN8XW6GqX0gJqJkt3B6Pkaul6FVo,156
|
||||
glean_parser/templates/ruby_server.jinja2,sha256=B0pbuld3j_0s7uMjoaCo8_6ehJUZeTXZlZZ9QRS4J_8,6252
|
||||
glean_parser/templates/rust.jinja2,sha256=hX8p5HXQNEeVz_sF6SDIyUNus6CcaCG9KWLl6uQLiOU,7285
|
||||
glean_parser/templates/rust.jinja2,sha256=mdYEsldHLMb2Hkzly-NJzkFINg7qMZo7MjDI_2ZqS3U,7247
|
||||
glean_parser/templates/rust_server.jinja2,sha256=JJdeU5jiWx9aWpF0qiXIYztJ14OQKxV3VFdAbCrtR_0,12841
|
||||
glean_parser/templates/swift.jinja2,sha256=L_JpwGLVzmOf1FYLoCzFu_RnGTExCIDup7iR1tWzD3o,6912
|
||||
glean_parser-17.0.1.dist-info/AUTHORS.md,sha256=yxgj8MioO4wUnrh0gmfb8l3DJJrf-l4HmmEDbQsbbNI,455
|
||||
glean_parser-17.0.1.dist-info/LICENSE,sha256=HyVuytGSiAUQ6ErWBHTqt1iSGHhLmlC8fO7jTCuR8dU,16725
|
||||
glean_parser-17.0.1.dist-info/METADATA,sha256=fX3p807Z0tgo8pjTGNX4Fxw3gPXT6dJrW_Cw7lnAE_4,36761
|
||||
glean_parser-17.0.1.dist-info/WHEEL,sha256=cVxcB9AmuTcXqmwrtPhNK88dr7IR_b6qagTj0UvIEbY,91
|
||||
glean_parser-17.0.1.dist-info/entry_points.txt,sha256=mf9d3sv8BwSjjR58x9KDnpVkONCnv3fPQC2NjJl15Xg,68
|
||||
glean_parser-17.0.1.dist-info/top_level.txt,sha256=q7T3duD-9tYZFyDry6Wv2LcdMsK2jGnzdDFhxWcT2Z8,13
|
||||
glean_parser-17.0.1.dist-info/RECORD,,
|
||||
glean_parser/templates/swift.jinja2,sha256=EAenC__ReGA2A4tn-ui3n849PVHxE5IndXUivXDh8AU,6841
|
||||
glean_parser-16.2.0.dist-info/AUTHORS.md,sha256=yxgj8MioO4wUnrh0gmfb8l3DJJrf-l4HmmEDbQsbbNI,455
|
||||
glean_parser-16.2.0.dist-info/LICENSE,sha256=HyVuytGSiAUQ6ErWBHTqt1iSGHhLmlC8fO7jTCuR8dU,16725
|
||||
glean_parser-16.2.0.dist-info/METADATA,sha256=rY8wmuwWXN1DnL3-VguHQr08H2WUoNlzvPgrfYIkVkU,36477
|
||||
glean_parser-16.2.0.dist-info/WHEEL,sha256=cVxcB9AmuTcXqmwrtPhNK88dr7IR_b6qagTj0UvIEbY,91
|
||||
glean_parser-16.2.0.dist-info/entry_points.txt,sha256=mf9d3sv8BwSjjR58x9KDnpVkONCnv3fPQC2NjJl15Xg,68
|
||||
glean_parser-16.2.0.dist-info/top_level.txt,sha256=q7T3duD-9tYZFyDry6Wv2LcdMsK2jGnzdDFhxWcT2Z8,13
|
||||
glean_parser-16.2.0.dist-info/RECORD,,
|
||||
@@ -26,7 +26,6 @@ class Ping:
|
||||
notification_emails: List[str],
|
||||
metadata: Optional[Dict] = None,
|
||||
data_reviews: Optional[List[str]] = None,
|
||||
uploader_capabilities: Optional[List[str]] = None,
|
||||
include_client_id: bool = False,
|
||||
send_if_empty: bool = False,
|
||||
reasons: Optional[Dict[str, str]] = None,
|
||||
@@ -58,9 +57,6 @@ class Ping:
|
||||
if data_reviews is None:
|
||||
data_reviews = []
|
||||
self.data_reviews = data_reviews
|
||||
if not uploader_capabilities:
|
||||
uploader_capabilities = []
|
||||
self.uploader_capabilities = uploader_capabilities
|
||||
self.include_client_id = include_client_id
|
||||
self.send_if_empty = send_if_empty
|
||||
if reasons is None:
|
||||
|
||||
@@ -127,21 +127,6 @@ additionalProperties:
|
||||
only takes effect when `metadata.include_info_sections` is `true`.
|
||||
type: boolean
|
||||
|
||||
uploader_capabilities:
|
||||
title: Uploader Capabilities
|
||||
description: |
|
||||
**Optional.**
|
||||
|
||||
An optional list of capability strings that the ping uploader must be
|
||||
capable of supporting in order to upload this ping.
|
||||
These are supplied exactly as defined (including order) to the uploader
|
||||
every time upload is attempted for this ping.
|
||||
The uploader must only attempt upload if it satisfies the supplied
|
||||
capabilities. If not, it must refuse to upload the ping.
|
||||
type: [array, "null"]
|
||||
items:
|
||||
type: string
|
||||
|
||||
send_if_empty:
|
||||
title: Send if empty
|
||||
description: |
|
||||
|
||||
@@ -97,7 +97,7 @@ CommonMetricData {
|
||||
/// {{ obj.description|wordwrap() | replace('\n', '\n/// ') }}
|
||||
#[rustfmt::skip]
|
||||
pub static {{ obj.name|snake_case }}: ::glean::private::__export::Lazy<::glean::private::PingType> =
|
||||
::glean::private::__export::Lazy::new(|| ::glean::private::PingType::new("{{ obj.name }}", {{ obj.include_client_id|rust }}, {{ obj.send_if_empty|rust }}, {{ obj.precise_timestamps|rust }}, {{ obj.include_info_sections|rust }}, {{ obj.enabled|rust }}, {{ obj.schedules_pings|rust }}, {{ obj.reason_codes|rust }}, {{ obj.follows_collection_enabled|rust }}, {{ obj.uploader_capabilities|rust }}));
|
||||
::glean::private::__export::Lazy::new(|| ::glean::private::PingType::new("{{ obj.name }}", {{ obj.include_client_id|rust }}, {{ obj.send_if_empty|rust }}, {{ obj.precise_timestamps|rust }}, {{ obj.include_info_sections|rust }}, {{ obj.enabled|rust }}, {{ obj.schedules_pings|rust }}, {{ obj.reason_codes|rust }}, {{ obj.follows_collection_enabled|rust }}));
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
pub mod {{ category.name|snake_case }} {
|
||||
|
||||
@@ -144,8 +144,7 @@ extension {{ namespace }} {
|
||||
enabled: {{obj.enabled|swift}},
|
||||
schedulesPings: {{obj.schedules_pings|swift}},
|
||||
reasonCodes: {{obj.reason_codes|swift}},
|
||||
followsCollectionEnabled: {{obj.follows_collection_enabled|swift}},
|
||||
uploaderCapabilities: {{obj.uploader_capabilities|swift}}
|
||||
followsCollectionEnabled: {{obj.follows_collection_enabled|swift}}
|
||||
)
|
||||
|
||||
{% endfor %}
|
||||
|
||||
@@ -546,7 +546,6 @@ ping_args = [
|
||||
"schedules_pings",
|
||||
"reason_codes",
|
||||
"follows_collection_enabled",
|
||||
"uploader_capabilities",
|
||||
]
|
||||
|
||||
|
||||
|
||||
2
third_party/python/pyproject.toml
vendored
2
third_party/python/pyproject.toml
vendored
@@ -21,7 +21,7 @@ dependencies = [
|
||||
"filelock~=3.6",
|
||||
"fluent-migrate==0.13.2",
|
||||
"fluent-syntax==0.19.0",
|
||||
"glean-parser==17.0.1",
|
||||
"glean-parser==16.2.0",
|
||||
"importlib-metadata==6.0.0",
|
||||
# Required for compatibility with Flask >= 2 in tools/tryselect/selectors/chooser
|
||||
"jinja2==3.1.2",
|
||||
|
||||
6
third_party/python/requirements.txt
vendored
6
third_party/python/requirements.txt
vendored
@@ -358,9 +358,9 @@ gitignorant==0.3.1 \
|
||||
giturlparse==0.12.0 \
|
||||
--hash=sha256:c0fff7c21acc435491b1779566e038757a205c1ffdcb47e4f81ea52ad8c3859a \
|
||||
--hash=sha256:412b74f2855f1da2fefa89fd8dde62df48476077a72fc19b62039554d27360eb
|
||||
glean-parser==17.0.1 \
|
||||
--hash=sha256:764a3b5aaa22d6100100d97a6ce58515687f4e0d06660180024e3101a507f580 \
|
||||
--hash=sha256:922b75be353461875802a50dfd052215414dbc2965d153b95ff31d85081c40b7
|
||||
glean-parser==16.2.0 \
|
||||
--hash=sha256:4f6794b41b6e69cbceaee2a5b835a74cdfe443d1fbf4e2656ac40ba72cc27458 \
|
||||
--hash=sha256:dc521d87b6d9c04f2006509be0aa2cdf0e923338521d9acad221d4e23caaace8
|
||||
idna==3.10 \
|
||||
--hash=sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9 \
|
||||
--hash=sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3
|
||||
|
||||
8
third_party/python/uv.lock
generated
vendored
8
third_party/python/uv.lock
generated
vendored
@@ -598,7 +598,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "glean-parser"
|
||||
version = "17.0.1"
|
||||
version = "16.2.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "click" },
|
||||
@@ -608,9 +608,9 @@ dependencies = [
|
||||
{ name = "platformdirs" },
|
||||
{ name = "pyyaml" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/7d/fd/895160c0fbc1ced0803bd19a2c2473f537efd8e6afa38aae2af12d5535b9/glean_parser-17.0.1.tar.gz", hash = "sha256:764a3b5aaa22d6100100d97a6ce58515687f4e0d06660180024e3101a507f580", size = 290273 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/88/74/c9d3ca070ca08399b5ee32d4f85adab9fe95faf44785655fbd283c20f4cb/glean_parser-16.2.0.tar.gz", hash = "sha256:4f6794b41b6e69cbceaee2a5b835a74cdfe443d1fbf4e2656ac40ba72cc27458", size = 289721 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/2d/02/dcc2f155ef74fb2c83d51b7170236f4648adb49f645bac4e5786dc3ac77c/glean_parser-17.0.1-py3-none-any.whl", hash = "sha256:922b75be353461875802a50dfd052215414dbc2965d153b95ff31d85081c40b7", size = 124106 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7c/2b/b7cedca86929673c89f4350e257ab720a6ea014a684b99c2814ad279b716/glean_parser-16.2.0-py3-none-any.whl", hash = "sha256:dc521d87b6d9c04f2006509be0aa2cdf0e923338521d9acad221d4e23caaace8", size = 123785 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -925,7 +925,7 @@ requires-dist = [
|
||||
{ name = "filelock", specifier = "~=3.6" },
|
||||
{ name = "fluent-migrate", specifier = "==0.13.2" },
|
||||
{ name = "fluent-syntax", specifier = "==0.19.0" },
|
||||
{ name = "glean-parser", specifier = "==17.0.1" },
|
||||
{ name = "glean-parser", specifier = "==16.2.0" },
|
||||
{ name = "importlib-metadata", specifier = "==6.0.0" },
|
||||
{ name = "jinja2", specifier = "==3.1.2" },
|
||||
{ name = "jsmin", specifier = "==3.0.0" },
|
||||
|
||||
2
third_party/python/uv.lock.hash
vendored
2
third_party/python/uv.lock.hash
vendored
@@ -1 +1 @@
|
||||
6811e7a47781ee2d8b491fa59de0ad7a40375d04beeab0f203d5e423f0db5e48
|
||||
dafec412f602d87682118ce75e91a25ed9ad9d9841b6667a3e9727dad246839b
|
||||
1
third_party/rust/askama/.cargo-checksum.json
vendored
Normal file
1
third_party/rust/askama/.cargo-checksum.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"files":{"Cargo.toml":"fbab611fc3ba2204942300a534b4f030460f33b0606fa50b9ad08ea567ba81e8","LICENSE-APACHE":"87cb0d734c723c083e51c825930ff42bce28596b52dee15567f6b28f19c195e3","LICENSE-MIT":"df20e0180764bf5bd76f74d47bc9e8c0069a666401629c390003a1d5eba99c92","README.md":"6a4430cf614ff9d36ba01463a8f94085ed4b0889fd719793fa914568247acce2","src/error.rs":"1e3f8020092469090f314f60685c077347e730a88222dfdaa38aaf2396507532","src/filters/json.rs":"dccd0a3f1017da9f6cd9650bd39eb1670f4a9833d2f0968614cd8cd65d18a9dd","src/filters/mod.rs":"903d09599e62f56657b00b2aa577c9d2f963348dd12a1029e90e68549f78b1db","src/filters/yaml.rs":"4e641bedbe3666b334836fb6603fe7f718f7e90d8e33419acca624f50a580c3f","src/helpers.rs":"76e0422acd4ccba7b1735d6ab7622a93f6ec5a2fa89531111d877266784d5334","src/lib.rs":"3a6e4d0b3aadc7c391cbe59416504a719406303726122779281a3af1a7ad76a4"},"package":"47cbc3cf73fa8d9833727bbee4835ba5c421a0d65b72daf9a7b5d0e0f9cfb57e"}
|
||||
126
third_party/rust/askama/Cargo.toml
vendored
Normal file
126
third_party/rust/askama/Cargo.toml
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
|
||||
#
|
||||
# When uploading crates to the registry Cargo will automatically
|
||||
# "normalize" Cargo.toml files for maximal compatibility
|
||||
# with all versions of Cargo and also rewrite `path` dependencies
|
||||
# to registry (e.g., crates.io) dependencies.
|
||||
#
|
||||
# If you are reading this file be aware that the original Cargo.toml
|
||||
# will likely look very different (and much more reasonable).
|
||||
# See Cargo.toml.orig for the original contents.
|
||||
|
||||
[package]
|
||||
edition = "2021"
|
||||
rust-version = "1.58"
|
||||
name = "askama"
|
||||
version = "0.12.0"
|
||||
description = "Type-safe, compiled Jinja-like templates for Rust"
|
||||
homepage = "https://github.com/djc/askama"
|
||||
documentation = "https://docs.rs/askama"
|
||||
readme = "README.md"
|
||||
keywords = [
|
||||
"markup",
|
||||
"template",
|
||||
"jinja2",
|
||||
"html",
|
||||
]
|
||||
categories = ["template-engine"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
repository = "https://github.com/djc/askama"
|
||||
resolver = "1"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
features = [
|
||||
"config",
|
||||
"humansize",
|
||||
"num-traits",
|
||||
"serde-json",
|
||||
"serde-yaml",
|
||||
]
|
||||
|
||||
[dependencies.askama_derive]
|
||||
version = "0.12.0"
|
||||
|
||||
[dependencies.askama_escape]
|
||||
version = "0.10.3"
|
||||
|
||||
[dependencies.comrak]
|
||||
version = "0.16"
|
||||
optional = true
|
||||
default-features = false
|
||||
|
||||
[dependencies.dep_humansize]
|
||||
version = "2"
|
||||
optional = true
|
||||
package = "humansize"
|
||||
|
||||
[dependencies.dep_num_traits]
|
||||
version = "0.2.6"
|
||||
optional = true
|
||||
package = "num-traits"
|
||||
|
||||
[dependencies.percent-encoding]
|
||||
version = "2.1.0"
|
||||
optional = true
|
||||
|
||||
[dependencies.serde]
|
||||
version = "1.0"
|
||||
features = ["derive"]
|
||||
optional = true
|
||||
|
||||
[dependencies.serde_json]
|
||||
version = "1.0"
|
||||
optional = true
|
||||
|
||||
[dependencies.serde_yaml]
|
||||
version = "0.9"
|
||||
optional = true
|
||||
|
||||
[features]
|
||||
config = ["askama_derive/config"]
|
||||
default = [
|
||||
"config",
|
||||
"humansize",
|
||||
"num-traits",
|
||||
"urlencode",
|
||||
]
|
||||
humansize = [
|
||||
"askama_derive/humansize",
|
||||
"dep_humansize",
|
||||
]
|
||||
markdown = [
|
||||
"askama_derive/markdown",
|
||||
"comrak",
|
||||
]
|
||||
mime = []
|
||||
mime_guess = []
|
||||
num-traits = [
|
||||
"askama_derive/num-traits",
|
||||
"dep_num_traits",
|
||||
]
|
||||
serde-json = [
|
||||
"askama_derive/serde-json",
|
||||
"askama_escape/json",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
serde-yaml = [
|
||||
"askama_derive/serde-yaml",
|
||||
"serde",
|
||||
"serde_yaml",
|
||||
]
|
||||
urlencode = [
|
||||
"askama_derive/urlencode",
|
||||
"percent-encoding",
|
||||
]
|
||||
with-actix-web = ["askama_derive/with-actix-web"]
|
||||
with-axum = ["askama_derive/with-axum"]
|
||||
with-gotham = ["askama_derive/with-gotham"]
|
||||
with-hyper = ["askama_derive/with-hyper"]
|
||||
with-mendes = ["askama_derive/with-mendes"]
|
||||
with-rocket = ["askama_derive/with-rocket"]
|
||||
with-tide = ["askama_derive/with-tide"]
|
||||
with-warp = ["askama_derive/with-warp"]
|
||||
|
||||
[badges.maintenance]
|
||||
status = "actively-developed"
|
||||
96
third_party/rust/askama/README.md
vendored
Normal file
96
third_party/rust/askama/README.md
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
# Askama
|
||||
|
||||
[](https://docs.rs/askama/)
|
||||
[](https://crates.io/crates/askama)
|
||||
[](https://github.com/djc/askama/actions?query=workflow%3ACI)
|
||||
[](https://gitter.im/djc/askama)
|
||||
|
||||
Askama implements a template rendering engine based on [Jinja](https://jinja.palletsprojects.com/).
|
||||
It generates Rust code from your templates at compile time
|
||||
based on a user-defined `struct` to hold the template's context.
|
||||
See below for an example, or read [the book][docs].
|
||||
|
||||
**"Pretty exciting. I would love to use this already."** --
|
||||
[Armin Ronacher][mitsuhiko], creator of Jinja
|
||||
|
||||
All feedback welcome. Feel free to file bugs, requests for documentation and
|
||||
any other feedback to the [issue tracker][issues] or [tweet me][twitter].
|
||||
|
||||
Askama was created by and is maintained by Dirkjan Ochtman. If you are in a
|
||||
position to support ongoing maintenance and further development or use it
|
||||
in a for-profit context, please consider supporting my open source work on
|
||||
[Patreon][patreon].
|
||||
|
||||
### Feature highlights
|
||||
|
||||
* Construct templates using a familiar, easy-to-use syntax
|
||||
* Benefit from the safety provided by Rust's type system
|
||||
* Template code is compiled into your crate for [optimal performance][benchmarks]
|
||||
* Optional built-in support for Actix, Axum, Gotham, Mendes, Rocket, tide, and warp web frameworks
|
||||
* Debugging features to assist you in template development
|
||||
* Templates must be valid UTF-8 and produce UTF-8 when rendered
|
||||
* IDE support available in [JetBrains products](https://plugins.jetbrains.com/plugin/16591-askama-template-support)
|
||||
* Works on stable Rust
|
||||
|
||||
### Supported in templates
|
||||
|
||||
* Template inheritance
|
||||
* Loops, if/else statements and include support
|
||||
* Macro support
|
||||
* Variables (no mutability allowed)
|
||||
* Some built-in filters, and the ability to use your own
|
||||
* Whitespace suppressing with '-' markers
|
||||
* Opt-out HTML escaping
|
||||
* Syntax customization
|
||||
|
||||
[docs]: https://djc.github.io/askama/
|
||||
[fafhrd91]: https://github.com/fafhrd91
|
||||
[mitsuhiko]: http://lucumr.pocoo.org/
|
||||
[issues]: https://github.com/djc/askama/issues
|
||||
[twitter]: https://twitter.com/djco/
|
||||
[patreon]: https://www.patreon.com/dochtman
|
||||
[benchmarks]: https://github.com/djc/template-benchmarks-rs
|
||||
|
||||
|
||||
How to get started
|
||||
------------------
|
||||
|
||||
First, add the following to your crate's `Cargo.toml`:
|
||||
|
||||
```toml
|
||||
# in section [dependencies]
|
||||
askama = "0.11.2"
|
||||
|
||||
```
|
||||
|
||||
Now create a directory called `templates` in your crate root.
|
||||
In it, create a file called `hello.html`, containing the following:
|
||||
|
||||
```
|
||||
Hello, {{ name }}!
|
||||
```
|
||||
|
||||
In any Rust file inside your crate, add the following:
|
||||
|
||||
```rust
|
||||
use askama::Template; // bring trait in scope
|
||||
|
||||
#[derive(Template)] // this will generate the code...
|
||||
#[template(path = "hello.html")] // using the template in this path, relative
|
||||
// to the `templates` dir in the crate root
|
||||
struct HelloTemplate<'a> { // the name of the struct can be anything
|
||||
name: &'a str, // the field name should match the variable name
|
||||
// in your template
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let hello = HelloTemplate { name: "world" }; // instantiate your struct
|
||||
println!("{}", hello.render().unwrap()); // then render it.
|
||||
}
|
||||
```
|
||||
|
||||
You should now be able to compile and run this code.
|
||||
|
||||
Review the [test cases] for more examples.
|
||||
|
||||
[test cases]: https://github.com/djc/askama/tree/main/testing
|
||||
@@ -1,10 +1,8 @@
|
||||
use std::convert::Infallible;
|
||||
use std::fmt::{self, Display};
|
||||
|
||||
/// The [`Result`](std::result::Result) type with [`Error`] as default error type
|
||||
pub type Result<I, E = Error> = std::result::Result<I, E>;
|
||||
pub type Result<I, E = Error> = ::std::result::Result<I, E>;
|
||||
|
||||
/// rinja error type
|
||||
/// askama error type
|
||||
///
|
||||
/// # Feature Interaction
|
||||
///
|
||||
@@ -23,25 +21,34 @@ pub type Result<I, E = Error> = std::result::Result<I, E>;
|
||||
/// using a adapter the benefits `failure` would
|
||||
/// bring to this crate are small, which is why
|
||||
/// `std::error::Error` was used.
|
||||
///
|
||||
#[non_exhaustive]
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
/// formatting error
|
||||
Fmt,
|
||||
Fmt(fmt::Error),
|
||||
|
||||
/// an error raised by using `?` in a template
|
||||
Custom(Box<dyn std::error::Error + Send + Sync>),
|
||||
|
||||
/// json conversion error
|
||||
#[cfg(feature = "serde_json")]
|
||||
Json(serde_json::Error),
|
||||
Json(::serde_json::Error),
|
||||
|
||||
/// yaml conversion error
|
||||
#[cfg(feature = "serde_yaml")]
|
||||
Yaml(::serde_yaml::Error),
|
||||
}
|
||||
|
||||
impl std::error::Error for Error {
|
||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||
match *self {
|
||||
Error::Fmt => None,
|
||||
Error::Fmt(ref err) => Some(err),
|
||||
Error::Custom(ref err) => Some(err.as_ref()),
|
||||
#[cfg(feature = "serde_json")]
|
||||
Error::Json(ref err) => Some(err),
|
||||
#[cfg(feature = "serde_yaml")]
|
||||
Error::Yaml(ref err) => Some(err),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,33 +56,33 @@ impl std::error::Error for Error {
|
||||
impl Display for Error {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Error::Fmt => write!(formatter, "formatting error"),
|
||||
Error::Fmt(err) => write!(formatter, "formatting error: {err}"),
|
||||
Error::Custom(err) => write!(formatter, "{err}"),
|
||||
#[cfg(feature = "serde_json")]
|
||||
Error::Json(err) => write!(formatter, "json conversion error: {err}"),
|
||||
#[cfg(feature = "serde_yaml")]
|
||||
Error::Yaml(err) => write!(formatter, "yaml conversion error: {}", err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<fmt::Error> for Error {
|
||||
#[inline]
|
||||
fn from(_: fmt::Error) -> Self {
|
||||
Error::Fmt
|
||||
fn from(err: fmt::Error) -> Self {
|
||||
Error::Fmt(err)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde_json")]
|
||||
impl From<serde_json::Error> for Error {
|
||||
#[inline]
|
||||
fn from(err: serde_json::Error) -> Self {
|
||||
impl From<::serde_json::Error> for Error {
|
||||
fn from(err: ::serde_json::Error) -> Self {
|
||||
Error::Json(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Infallible> for Error {
|
||||
#[inline]
|
||||
fn from(value: Infallible) -> Self {
|
||||
match value {}
|
||||
#[cfg(feature = "serde_yaml")]
|
||||
impl From<::serde_yaml::Error> for Error {
|
||||
fn from(err: ::serde_yaml::Error) -> Self {
|
||||
Error::Yaml(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +90,6 @@ impl From<Infallible> for Error {
|
||||
mod tests {
|
||||
use super::Error;
|
||||
|
||||
#[allow(dead_code)]
|
||||
trait AssertSendSyncStatic: Send + Sync + 'static {}
|
||||
impl AssertSendSyncStatic for Error {}
|
||||
}
|
||||
44
third_party/rust/askama/src/filters/json.rs
vendored
Normal file
44
third_party/rust/askama/src/filters/json.rs
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
use crate::error::{Error, Result};
|
||||
use askama_escape::JsonEscapeBuffer;
|
||||
use serde::Serialize;
|
||||
use serde_json::to_writer_pretty;
|
||||
|
||||
/// Serialize to JSON (requires `json` feature)
|
||||
///
|
||||
/// The generated string does not contain ampersands `&`, chevrons `< >`, or apostrophes `'`.
|
||||
/// To use it in a `<script>` you can combine it with the safe filter:
|
||||
///
|
||||
/// ``` html
|
||||
/// <script>
|
||||
/// var data = {{data|json|safe}};
|
||||
/// </script>
|
||||
/// ```
|
||||
///
|
||||
/// To use it in HTML attributes, you can either use it in quotation marks `"{{data|json}}"` as is,
|
||||
/// or in apostrophes with the (optional) safe filter `'{{data|json|safe}}'`.
|
||||
/// In HTML texts the output of e.g. `<pre>{{data|json|safe}}</pre>` is safe, too.
|
||||
pub fn json<S: Serialize>(s: S) -> Result<String> {
|
||||
let mut writer = JsonEscapeBuffer::new();
|
||||
to_writer_pretty(&mut writer, &s).map_err(Error::from)?;
|
||||
Ok(writer.finish())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_json() {
|
||||
assert_eq!(json(true).unwrap(), "true");
|
||||
assert_eq!(json("foo").unwrap(), r#""foo""#);
|
||||
assert_eq!(json(true).unwrap(), "true");
|
||||
assert_eq!(json("foo").unwrap(), r#""foo""#);
|
||||
assert_eq!(
|
||||
json(vec!["foo", "bar"]).unwrap(),
|
||||
r#"[
|
||||
"foo",
|
||||
"bar"
|
||||
]"#
|
||||
);
|
||||
}
|
||||
}
|
||||
640
third_party/rust/askama/src/filters/mod.rs
vendored
Normal file
640
third_party/rust/askama/src/filters/mod.rs
vendored
Normal file
@@ -0,0 +1,640 @@
|
||||
//! Module for built-in filter functions
|
||||
//!
|
||||
//! Contains all the built-in filter functions for use in templates.
|
||||
//! You can define your own filters, as well.
|
||||
//! For more information, read the [book](https://djc.github.io/askama/filters.html).
|
||||
#![allow(clippy::trivially_copy_pass_by_ref)]
|
||||
|
||||
use std::fmt::{self, Write};
|
||||
|
||||
#[cfg(feature = "serde-json")]
|
||||
mod json;
|
||||
#[cfg(feature = "serde-json")]
|
||||
pub use self::json::json;
|
||||
|
||||
#[cfg(feature = "serde-yaml")]
|
||||
mod yaml;
|
||||
#[cfg(feature = "serde-yaml")]
|
||||
pub use self::yaml::yaml;
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use crate::error::Error::Fmt;
|
||||
use askama_escape::{Escaper, MarkupDisplay};
|
||||
#[cfg(feature = "humansize")]
|
||||
use dep_humansize::{format_size_i, ToF64, DECIMAL};
|
||||
#[cfg(feature = "num-traits")]
|
||||
use dep_num_traits::{cast::NumCast, Signed};
|
||||
#[cfg(feature = "percent-encoding")]
|
||||
use percent_encoding::{utf8_percent_encode, AsciiSet, NON_ALPHANUMERIC};
|
||||
|
||||
use super::Result;
|
||||
|
||||
#[cfg(feature = "percent-encoding")]
|
||||
// Urlencode char encoding set. Only the characters in the unreserved set don't
|
||||
// have any special purpose in any part of a URI and can be safely left
|
||||
// unencoded as specified in https://tools.ietf.org/html/rfc3986.html#section-2.3
|
||||
const URLENCODE_STRICT_SET: &AsciiSet = &NON_ALPHANUMERIC
|
||||
.remove(b'_')
|
||||
.remove(b'.')
|
||||
.remove(b'-')
|
||||
.remove(b'~');
|
||||
|
||||
#[cfg(feature = "percent-encoding")]
|
||||
// Same as URLENCODE_STRICT_SET, but preserves forward slashes for encoding paths
|
||||
const URLENCODE_SET: &AsciiSet = &URLENCODE_STRICT_SET.remove(b'/');
|
||||
|
||||
/// Marks a string (or other `Display` type) as safe
|
||||
///
|
||||
/// Use this is you want to allow markup in an expression, or if you know
|
||||
/// that the expression's contents don't need to be escaped.
|
||||
///
|
||||
/// Askama will automatically insert the first (`Escaper`) argument,
|
||||
/// so this filter only takes a single argument of any type that implements
|
||||
/// `Display`.
|
||||
pub fn safe<E, T>(e: E, v: T) -> Result<MarkupDisplay<E, T>>
|
||||
where
|
||||
E: Escaper,
|
||||
T: fmt::Display,
|
||||
{
|
||||
Ok(MarkupDisplay::new_safe(v, e))
|
||||
}
|
||||
|
||||
/// Escapes strings according to the escape mode.
|
||||
///
|
||||
/// Askama will automatically insert the first (`Escaper`) argument,
|
||||
/// so this filter only takes a single argument of any type that implements
|
||||
/// `Display`.
|
||||
///
|
||||
/// It is possible to optionally specify an escaper other than the default for
|
||||
/// the template's extension, like `{{ val|escape("txt") }}`.
|
||||
pub fn escape<E, T>(e: E, v: T) -> Result<MarkupDisplay<E, T>>
|
||||
where
|
||||
E: Escaper,
|
||||
T: fmt::Display,
|
||||
{
|
||||
Ok(MarkupDisplay::new_unsafe(v, e))
|
||||
}
|
||||
|
||||
#[cfg(feature = "humansize")]
|
||||
/// Returns adequate string representation (in KB, ..) of number of bytes
|
||||
pub fn filesizeformat(b: &(impl ToF64 + Copy)) -> Result<String> {
|
||||
Ok(format_size_i(*b, DECIMAL))
|
||||
}
|
||||
|
||||
#[cfg(feature = "percent-encoding")]
|
||||
/// Percent-encodes the argument for safe use in URI; does not encode `/`.
|
||||
///
|
||||
/// This should be safe for all parts of URI (paths segments, query keys, query
|
||||
/// values). In the rare case that the server can't deal with forward slashes in
|
||||
/// the query string, use [`urlencode_strict`], which encodes them as well.
|
||||
///
|
||||
/// Encodes all characters except ASCII letters, digits, and `_.-~/`. In other
|
||||
/// words, encodes all characters which are not in the unreserved set,
|
||||
/// as specified by [RFC3986](https://tools.ietf.org/html/rfc3986#section-2.3),
|
||||
/// with the exception of `/`.
|
||||
///
|
||||
/// ```none,ignore
|
||||
/// <a href="/metro{{ "/stations/Château d'Eau"|urlencode }}">Station</a>
|
||||
/// <a href="/page?text={{ "look, unicode/emojis ✨"|urlencode }}">Page</a>
|
||||
/// ```
|
||||
///
|
||||
/// To encode `/` as well, see [`urlencode_strict`](./fn.urlencode_strict.html).
|
||||
///
|
||||
/// [`urlencode_strict`]: ./fn.urlencode_strict.html
|
||||
pub fn urlencode<T: fmt::Display>(s: T) -> Result<String> {
|
||||
let s = s.to_string();
|
||||
Ok(utf8_percent_encode(&s, URLENCODE_SET).to_string())
|
||||
}
|
||||
|
||||
#[cfg(feature = "percent-encoding")]
|
||||
/// Percent-encodes the argument for safe use in URI; encodes `/`.
|
||||
///
|
||||
/// Use this filter for encoding query keys and values in the rare case that
|
||||
/// the server can't process them unencoded.
|
||||
///
|
||||
/// Encodes all characters except ASCII letters, digits, and `_.-~`. In other
|
||||
/// words, encodes all characters which are not in the unreserved set,
|
||||
/// as specified by [RFC3986](https://tools.ietf.org/html/rfc3986#section-2.3).
|
||||
///
|
||||
/// ```none,ignore
|
||||
/// <a href="/page?text={{ "look, unicode/emojis ✨"|urlencode_strict }}">Page</a>
|
||||
/// ```
|
||||
///
|
||||
/// If you want to preserve `/`, see [`urlencode`](./fn.urlencode.html).
|
||||
pub fn urlencode_strict<T: fmt::Display>(s: T) -> Result<String> {
|
||||
let s = s.to_string();
|
||||
Ok(utf8_percent_encode(&s, URLENCODE_STRICT_SET).to_string())
|
||||
}
|
||||
|
||||
/// Formats arguments according to the specified format
|
||||
///
|
||||
/// The *second* argument to this filter must be a string literal (as in normal
|
||||
/// Rust). The two arguments are passed through to the `format!()`
|
||||
/// [macro](https://doc.rust-lang.org/stable/std/macro.format.html) by
|
||||
/// the Askama code generator, but the order is swapped to support filter
|
||||
/// composition.
|
||||
///
|
||||
/// ```ignore
|
||||
/// {{ value | fmt("{:?}") }}
|
||||
/// ```
|
||||
///
|
||||
/// Compare with [format](./fn.format.html).
|
||||
pub fn fmt() {}
|
||||
|
||||
/// Formats arguments according to the specified format
|
||||
///
|
||||
/// The first argument to this filter must be a string literal (as in normal
|
||||
/// Rust). All arguments are passed through to the `format!()`
|
||||
/// [macro](https://doc.rust-lang.org/stable/std/macro.format.html) by
|
||||
/// the Askama code generator.
|
||||
///
|
||||
/// ```ignore
|
||||
/// {{ "{:?}{:?}" | format(value, other_value) }}
|
||||
/// ```
|
||||
///
|
||||
/// Compare with [fmt](./fn.fmt.html).
|
||||
pub fn format() {}
|
||||
|
||||
/// Replaces line breaks in plain text with appropriate HTML
|
||||
///
|
||||
/// A single newline becomes an HTML line break `<br>` and a new line
|
||||
/// followed by a blank line becomes a paragraph break `<p>`.
|
||||
pub fn linebreaks<T: fmt::Display>(s: T) -> Result<String> {
|
||||
let s = s.to_string();
|
||||
let linebroken = s.replace("\n\n", "</p><p>").replace('\n', "<br/>");
|
||||
|
||||
Ok(format!("<p>{linebroken}</p>"))
|
||||
}
|
||||
|
||||
/// Converts all newlines in a piece of plain text to HTML line breaks
|
||||
pub fn linebreaksbr<T: fmt::Display>(s: T) -> Result<String> {
|
||||
let s = s.to_string();
|
||||
Ok(s.replace('\n', "<br/>"))
|
||||
}
|
||||
|
||||
/// Replaces only paragraph breaks in plain text with appropriate HTML
|
||||
///
|
||||
/// A new line followed by a blank line becomes a paragraph break `<p>`.
|
||||
/// Paragraph tags only wrap content; empty paragraphs are removed.
|
||||
/// No `<br/>` tags are added.
|
||||
pub fn paragraphbreaks<T: fmt::Display>(s: T) -> Result<String> {
|
||||
let s = s.to_string();
|
||||
let linebroken = s.replace("\n\n", "</p><p>").replace("<p></p>", "");
|
||||
|
||||
Ok(format!("<p>{linebroken}</p>"))
|
||||
}
|
||||
|
||||
/// Converts to lowercase
|
||||
pub fn lower<T: fmt::Display>(s: T) -> Result<String> {
|
||||
let s = s.to_string();
|
||||
Ok(s.to_lowercase())
|
||||
}
|
||||
|
||||
/// Alias for the `lower()` filter
|
||||
pub fn lowercase<T: fmt::Display>(s: T) -> Result<String> {
|
||||
lower(s)
|
||||
}
|
||||
|
||||
/// Converts to uppercase
|
||||
pub fn upper<T: fmt::Display>(s: T) -> Result<String> {
|
||||
let s = s.to_string();
|
||||
Ok(s.to_uppercase())
|
||||
}
|
||||
|
||||
/// Alias for the `upper()` filter
|
||||
pub fn uppercase<T: fmt::Display>(s: T) -> Result<String> {
|
||||
upper(s)
|
||||
}
|
||||
|
||||
/// Strip leading and trailing whitespace
|
||||
pub fn trim<T: fmt::Display>(s: T) -> Result<String> {
|
||||
let s = s.to_string();
|
||||
Ok(s.trim().to_owned())
|
||||
}
|
||||
|
||||
/// Limit string length, appends '...' if truncated
|
||||
pub fn truncate<T: fmt::Display>(s: T, len: usize) -> Result<String> {
|
||||
let mut s = s.to_string();
|
||||
if s.len() > len {
|
||||
let mut real_len = len;
|
||||
while !s.is_char_boundary(real_len) {
|
||||
real_len += 1;
|
||||
}
|
||||
s.truncate(real_len);
|
||||
s.push_str("...");
|
||||
}
|
||||
Ok(s)
|
||||
}
|
||||
|
||||
/// Indent lines with `width` spaces
|
||||
pub fn indent<T: fmt::Display>(s: T, width: usize) -> Result<String> {
|
||||
let s = s.to_string();
|
||||
|
||||
let mut indented = String::new();
|
||||
|
||||
for (i, c) in s.char_indices() {
|
||||
indented.push(c);
|
||||
|
||||
if c == '\n' && i < s.len() - 1 {
|
||||
for _ in 0..width {
|
||||
indented.push(' ');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(indented)
|
||||
}
|
||||
|
||||
#[cfg(feature = "num-traits")]
|
||||
/// Casts number to f64
|
||||
pub fn into_f64<T>(number: T) -> Result<f64>
|
||||
where
|
||||
T: NumCast,
|
||||
{
|
||||
number.to_f64().ok_or(Fmt(fmt::Error))
|
||||
}
|
||||
|
||||
#[cfg(feature = "num-traits")]
|
||||
/// Casts number to isize
|
||||
pub fn into_isize<T>(number: T) -> Result<isize>
|
||||
where
|
||||
T: NumCast,
|
||||
{
|
||||
number.to_isize().ok_or(Fmt(fmt::Error))
|
||||
}
|
||||
|
||||
/// Joins iterable into a string separated by provided argument
|
||||
pub fn join<T, I, S>(input: I, separator: S) -> Result<String>
|
||||
where
|
||||
T: fmt::Display,
|
||||
I: Iterator<Item = T>,
|
||||
S: AsRef<str>,
|
||||
{
|
||||
let separator: &str = separator.as_ref();
|
||||
|
||||
let mut rv = String::new();
|
||||
|
||||
for (num, item) in input.enumerate() {
|
||||
if num > 0 {
|
||||
rv.push_str(separator);
|
||||
}
|
||||
|
||||
write!(rv, "{item}")?;
|
||||
}
|
||||
|
||||
Ok(rv)
|
||||
}
|
||||
|
||||
#[cfg(feature = "num-traits")]
|
||||
/// Absolute value
|
||||
pub fn abs<T>(number: T) -> Result<T>
|
||||
where
|
||||
T: Signed,
|
||||
{
|
||||
Ok(number.abs())
|
||||
}
|
||||
|
||||
/// Capitalize a value. The first character will be uppercase, all others lowercase.
|
||||
pub fn capitalize<T: fmt::Display>(s: T) -> Result<String> {
|
||||
let s = s.to_string();
|
||||
match s.chars().next() {
|
||||
Some(c) => {
|
||||
let mut replacement: String = c.to_uppercase().collect();
|
||||
replacement.push_str(&s[c.len_utf8()..].to_lowercase());
|
||||
Ok(replacement)
|
||||
}
|
||||
_ => Ok(s),
|
||||
}
|
||||
}
|
||||
|
||||
/// Centers the value in a field of a given width
|
||||
pub fn center(src: &dyn fmt::Display, dst_len: usize) -> Result<String> {
|
||||
let src = src.to_string();
|
||||
let len = src.len();
|
||||
|
||||
if dst_len <= len {
|
||||
Ok(src)
|
||||
} else {
|
||||
let diff = dst_len - len;
|
||||
let mid = diff / 2;
|
||||
let r = diff % 2;
|
||||
let mut buf = String::with_capacity(dst_len);
|
||||
|
||||
for _ in 0..mid {
|
||||
buf.push(' ');
|
||||
}
|
||||
|
||||
buf.push_str(&src);
|
||||
|
||||
for _ in 0..mid + r {
|
||||
buf.push(' ');
|
||||
}
|
||||
|
||||
Ok(buf)
|
||||
}
|
||||
}
|
||||
|
||||
/// Count the words in that string
|
||||
pub fn wordcount<T: fmt::Display>(s: T) -> Result<usize> {
|
||||
let s = s.to_string();
|
||||
|
||||
Ok(s.split_whitespace().count())
|
||||
}
|
||||
|
||||
#[cfg(feature = "markdown")]
|
||||
pub fn markdown<E, S>(
|
||||
e: E,
|
||||
s: S,
|
||||
options: Option<&comrak::ComrakOptions>,
|
||||
) -> Result<MarkupDisplay<E, String>>
|
||||
where
|
||||
E: Escaper,
|
||||
S: AsRef<str>,
|
||||
{
|
||||
use comrak::{
|
||||
markdown_to_html, ComrakExtensionOptions, ComrakOptions, ComrakParseOptions,
|
||||
ComrakRenderOptions, ListStyleType,
|
||||
};
|
||||
|
||||
const DEFAULT_OPTIONS: ComrakOptions = ComrakOptions {
|
||||
extension: ComrakExtensionOptions {
|
||||
strikethrough: true,
|
||||
tagfilter: true,
|
||||
table: true,
|
||||
autolink: true,
|
||||
// default:
|
||||
tasklist: false,
|
||||
superscript: false,
|
||||
header_ids: None,
|
||||
footnotes: false,
|
||||
description_lists: false,
|
||||
front_matter_delimiter: None,
|
||||
},
|
||||
parse: ComrakParseOptions {
|
||||
// default:
|
||||
smart: false,
|
||||
default_info_string: None,
|
||||
relaxed_tasklist_matching: false,
|
||||
},
|
||||
render: ComrakRenderOptions {
|
||||
unsafe_: false,
|
||||
escape: true,
|
||||
// default:
|
||||
hardbreaks: false,
|
||||
github_pre_lang: false,
|
||||
width: 0,
|
||||
list_style: ListStyleType::Dash,
|
||||
},
|
||||
};
|
||||
|
||||
let s = markdown_to_html(s.as_ref(), options.unwrap_or(&DEFAULT_OPTIONS));
|
||||
Ok(MarkupDisplay::new_safe(s, e))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
#[cfg(feature = "num-traits")]
|
||||
use std::f64::INFINITY;
|
||||
|
||||
#[cfg(feature = "humansize")]
|
||||
#[test]
|
||||
fn test_filesizeformat() {
|
||||
assert_eq!(filesizeformat(&0).unwrap(), "0 B");
|
||||
assert_eq!(filesizeformat(&999u64).unwrap(), "999 B");
|
||||
assert_eq!(filesizeformat(&1000i32).unwrap(), "1 kB");
|
||||
assert_eq!(filesizeformat(&1023).unwrap(), "1.02 kB");
|
||||
assert_eq!(filesizeformat(&1024usize).unwrap(), "1.02 kB");
|
||||
}
|
||||
|
||||
#[cfg(feature = "percent-encoding")]
|
||||
#[test]
|
||||
fn test_urlencoding() {
|
||||
// Unreserved (https://tools.ietf.org/html/rfc3986.html#section-2.3)
|
||||
// alpha / digit
|
||||
assert_eq!(urlencode("AZaz09").unwrap(), "AZaz09");
|
||||
assert_eq!(urlencode_strict("AZaz09").unwrap(), "AZaz09");
|
||||
// other
|
||||
assert_eq!(urlencode("_.-~").unwrap(), "_.-~");
|
||||
assert_eq!(urlencode_strict("_.-~").unwrap(), "_.-~");
|
||||
|
||||
// Reserved (https://tools.ietf.org/html/rfc3986.html#section-2.2)
|
||||
// gen-delims
|
||||
assert_eq!(urlencode(":/?#[]@").unwrap(), "%3A/%3F%23%5B%5D%40");
|
||||
assert_eq!(
|
||||
urlencode_strict(":/?#[]@").unwrap(),
|
||||
"%3A%2F%3F%23%5B%5D%40"
|
||||
);
|
||||
// sub-delims
|
||||
assert_eq!(
|
||||
urlencode("!$&'()*+,;=").unwrap(),
|
||||
"%21%24%26%27%28%29%2A%2B%2C%3B%3D"
|
||||
);
|
||||
assert_eq!(
|
||||
urlencode_strict("!$&'()*+,;=").unwrap(),
|
||||
"%21%24%26%27%28%29%2A%2B%2C%3B%3D"
|
||||
);
|
||||
|
||||
// Other
|
||||
assert_eq!(
|
||||
urlencode("žŠďŤňĚáÉóŮ").unwrap(),
|
||||
"%C5%BE%C5%A0%C4%8F%C5%A4%C5%88%C4%9A%C3%A1%C3%89%C3%B3%C5%AE"
|
||||
);
|
||||
assert_eq!(
|
||||
urlencode_strict("žŠďŤňĚáÉóŮ").unwrap(),
|
||||
"%C5%BE%C5%A0%C4%8F%C5%A4%C5%88%C4%9A%C3%A1%C3%89%C3%B3%C5%AE"
|
||||
);
|
||||
|
||||
// Ferris
|
||||
assert_eq!(urlencode("🦀").unwrap(), "%F0%9F%A6%80");
|
||||
assert_eq!(urlencode_strict("🦀").unwrap(), "%F0%9F%A6%80");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_linebreaks() {
|
||||
assert_eq!(
|
||||
linebreaks("Foo\nBar Baz").unwrap(),
|
||||
"<p>Foo<br/>Bar Baz</p>"
|
||||
);
|
||||
assert_eq!(
|
||||
linebreaks("Foo\nBar\n\nBaz").unwrap(),
|
||||
"<p>Foo<br/>Bar</p><p>Baz</p>"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_linebreaksbr() {
|
||||
assert_eq!(linebreaksbr("Foo\nBar").unwrap(), "Foo<br/>Bar");
|
||||
assert_eq!(
|
||||
linebreaksbr("Foo\nBar\n\nBaz").unwrap(),
|
||||
"Foo<br/>Bar<br/><br/>Baz"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_paragraphbreaks() {
|
||||
assert_eq!(
|
||||
paragraphbreaks("Foo\nBar Baz").unwrap(),
|
||||
"<p>Foo\nBar Baz</p>"
|
||||
);
|
||||
assert_eq!(
|
||||
paragraphbreaks("Foo\nBar\n\nBaz").unwrap(),
|
||||
"<p>Foo\nBar</p><p>Baz</p>"
|
||||
);
|
||||
assert_eq!(
|
||||
paragraphbreaks("Foo\n\n\n\n\nBar\n\nBaz").unwrap(),
|
||||
"<p>Foo</p><p>\nBar</p><p>Baz</p>"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_lower() {
|
||||
assert_eq!(lower("Foo").unwrap(), "foo");
|
||||
assert_eq!(lower("FOO").unwrap(), "foo");
|
||||
assert_eq!(lower("FooBar").unwrap(), "foobar");
|
||||
assert_eq!(lower("foo").unwrap(), "foo");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_upper() {
|
||||
assert_eq!(upper("Foo").unwrap(), "FOO");
|
||||
assert_eq!(upper("FOO").unwrap(), "FOO");
|
||||
assert_eq!(upper("FooBar").unwrap(), "FOOBAR");
|
||||
assert_eq!(upper("foo").unwrap(), "FOO");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_trim() {
|
||||
assert_eq!(trim(" Hello\tworld\t").unwrap(), "Hello\tworld");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_truncate() {
|
||||
assert_eq!(truncate("hello", 2).unwrap(), "he...");
|
||||
let a = String::from("您好");
|
||||
assert_eq!(a.len(), 6);
|
||||
assert_eq!(String::from("您").len(), 3);
|
||||
assert_eq!(truncate("您好", 1).unwrap(), "您...");
|
||||
assert_eq!(truncate("您好", 2).unwrap(), "您...");
|
||||
assert_eq!(truncate("您好", 3).unwrap(), "您...");
|
||||
assert_eq!(truncate("您好", 4).unwrap(), "您好...");
|
||||
assert_eq!(truncate("您好", 6).unwrap(), "您好");
|
||||
assert_eq!(truncate("您好", 7).unwrap(), "您好");
|
||||
let s = String::from("🤚a🤚");
|
||||
assert_eq!(s.len(), 9);
|
||||
assert_eq!(String::from("🤚").len(), 4);
|
||||
assert_eq!(truncate("🤚a🤚", 1).unwrap(), "🤚...");
|
||||
assert_eq!(truncate("🤚a🤚", 2).unwrap(), "🤚...");
|
||||
assert_eq!(truncate("🤚a🤚", 3).unwrap(), "🤚...");
|
||||
assert_eq!(truncate("🤚a🤚", 4).unwrap(), "🤚...");
|
||||
assert_eq!(truncate("🤚a🤚", 5).unwrap(), "🤚a...");
|
||||
assert_eq!(truncate("🤚a🤚", 6).unwrap(), "🤚a🤚...");
|
||||
assert_eq!(truncate("🤚a🤚", 9).unwrap(), "🤚a🤚");
|
||||
assert_eq!(truncate("🤚a🤚", 10).unwrap(), "🤚a🤚");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_indent() {
|
||||
assert_eq!(indent("hello", 2).unwrap(), "hello");
|
||||
assert_eq!(indent("hello\n", 2).unwrap(), "hello\n");
|
||||
assert_eq!(indent("hello\nfoo", 2).unwrap(), "hello\n foo");
|
||||
assert_eq!(
|
||||
indent("hello\nfoo\n bar", 4).unwrap(),
|
||||
"hello\n foo\n bar"
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "num-traits")]
|
||||
#[test]
|
||||
#[allow(clippy::float_cmp)]
|
||||
fn test_into_f64() {
|
||||
assert_eq!(into_f64(1).unwrap(), 1.0_f64);
|
||||
assert_eq!(into_f64(1.9).unwrap(), 1.9_f64);
|
||||
assert_eq!(into_f64(-1.9).unwrap(), -1.9_f64);
|
||||
assert_eq!(into_f64(INFINITY as f32).unwrap(), INFINITY);
|
||||
assert_eq!(into_f64(-INFINITY as f32).unwrap(), -INFINITY);
|
||||
}
|
||||
|
||||
#[cfg(feature = "num-traits")]
|
||||
#[test]
|
||||
fn test_into_isize() {
|
||||
assert_eq!(into_isize(1).unwrap(), 1_isize);
|
||||
assert_eq!(into_isize(1.9).unwrap(), 1_isize);
|
||||
assert_eq!(into_isize(-1.9).unwrap(), -1_isize);
|
||||
assert_eq!(into_isize(1.5_f64).unwrap(), 1_isize);
|
||||
assert_eq!(into_isize(-1.5_f64).unwrap(), -1_isize);
|
||||
match into_isize(INFINITY) {
|
||||
Err(Fmt(fmt::Error)) => {}
|
||||
_ => panic!("Should return error of type Err(Fmt(fmt::Error))"),
|
||||
};
|
||||
}
|
||||
|
||||
#[allow(clippy::needless_borrow)]
|
||||
#[test]
|
||||
fn test_join() {
|
||||
assert_eq!(
|
||||
join((&["hello", "world"]).iter(), ", ").unwrap(),
|
||||
"hello, world"
|
||||
);
|
||||
assert_eq!(join((&["hello"]).iter(), ", ").unwrap(), "hello");
|
||||
|
||||
let empty: &[&str] = &[];
|
||||
assert_eq!(join(empty.iter(), ", ").unwrap(), "");
|
||||
|
||||
let input: Vec<String> = vec!["foo".into(), "bar".into(), "bazz".into()];
|
||||
assert_eq!(join(input.iter(), ":").unwrap(), "foo:bar:bazz");
|
||||
|
||||
let input: &[String] = &["foo".into(), "bar".into()];
|
||||
assert_eq!(join(input.iter(), ":").unwrap(), "foo:bar");
|
||||
|
||||
let real: String = "blah".into();
|
||||
let input: Vec<&str> = vec![&real];
|
||||
assert_eq!(join(input.iter(), ";").unwrap(), "blah");
|
||||
|
||||
assert_eq!(
|
||||
join((&&&&&["foo", "bar"]).iter(), ", ").unwrap(),
|
||||
"foo, bar"
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "num-traits")]
|
||||
#[test]
|
||||
#[allow(clippy::float_cmp)]
|
||||
fn test_abs() {
|
||||
assert_eq!(abs(1).unwrap(), 1);
|
||||
assert_eq!(abs(-1).unwrap(), 1);
|
||||
assert_eq!(abs(1.0).unwrap(), 1.0);
|
||||
assert_eq!(abs(-1.0).unwrap(), 1.0);
|
||||
assert_eq!(abs(1.0_f64).unwrap(), 1.0_f64);
|
||||
assert_eq!(abs(-1.0_f64).unwrap(), 1.0_f64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_capitalize() {
|
||||
assert_eq!(capitalize("foo").unwrap(), "Foo".to_string());
|
||||
assert_eq!(capitalize("f").unwrap(), "F".to_string());
|
||||
assert_eq!(capitalize("fO").unwrap(), "Fo".to_string());
|
||||
assert_eq!(capitalize("").unwrap(), "".to_string());
|
||||
assert_eq!(capitalize("FoO").unwrap(), "Foo".to_string());
|
||||
assert_eq!(capitalize("foO BAR").unwrap(), "Foo bar".to_string());
|
||||
assert_eq!(capitalize("äØÄÅÖ").unwrap(), "Äøäåö".to_string());
|
||||
assert_eq!(capitalize("ß").unwrap(), "SS".to_string());
|
||||
assert_eq!(capitalize("ßß").unwrap(), "SSß".to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_center() {
|
||||
assert_eq!(center(&"f", 3).unwrap(), " f ".to_string());
|
||||
assert_eq!(center(&"f", 4).unwrap(), " f ".to_string());
|
||||
assert_eq!(center(&"foo", 1).unwrap(), "foo".to_string());
|
||||
assert_eq!(center(&"foo bar", 8).unwrap(), "foo bar ".to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_wordcount() {
|
||||
assert_eq!(wordcount("").unwrap(), 0);
|
||||
assert_eq!(wordcount(" \n\t").unwrap(), 0);
|
||||
assert_eq!(wordcount("foo").unwrap(), 1);
|
||||
assert_eq!(wordcount("foo bar").unwrap(), 2);
|
||||
}
|
||||
}
|
||||
34
third_party/rust/askama/src/filters/yaml.rs
vendored
Normal file
34
third_party/rust/askama/src/filters/yaml.rs
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
use crate::error::{Error, Result};
|
||||
use askama_escape::{Escaper, MarkupDisplay};
|
||||
use serde::Serialize;
|
||||
|
||||
/// Serialize to YAML (requires `serde_yaml` feature)
|
||||
///
|
||||
/// ## Errors
|
||||
///
|
||||
/// This will panic if `S`'s implementation of `Serialize` decides to fail,
|
||||
/// or if `T` contains a map with non-string keys.
|
||||
pub fn yaml<E: Escaper, S: Serialize>(e: E, s: S) -> Result<MarkupDisplay<E, String>> {
|
||||
match serde_yaml::to_string(&s) {
|
||||
Ok(s) => Ok(MarkupDisplay::new_safe(s, e)),
|
||||
Err(e) => Err(Error::from(e)),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use askama_escape::Html;
|
||||
|
||||
#[test]
|
||||
fn test_yaml() {
|
||||
assert_eq!(yaml(Html, true).unwrap().to_string(), "true\n");
|
||||
assert_eq!(yaml(Html, "foo").unwrap().to_string(), "foo\n");
|
||||
assert_eq!(yaml(Html, true).unwrap().to_string(), "true\n");
|
||||
assert_eq!(yaml(Html, "foo").unwrap().to_string(), "foo\n");
|
||||
assert_eq!(
|
||||
yaml(Html, &vec!["foo", "bar"]).unwrap().to_string(),
|
||||
"- foo\n- bar\n"
|
||||
);
|
||||
}
|
||||
}
|
||||
48
third_party/rust/askama/src/helpers.rs
vendored
Normal file
48
third_party/rust/askama/src/helpers.rs
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
use std::iter::{Enumerate, Peekable};
|
||||
|
||||
pub struct TemplateLoop<I>
|
||||
where
|
||||
I: Iterator,
|
||||
{
|
||||
iter: Peekable<Enumerate<I>>,
|
||||
}
|
||||
|
||||
impl<I> TemplateLoop<I>
|
||||
where
|
||||
I: Iterator,
|
||||
{
|
||||
#[inline]
|
||||
pub fn new(iter: I) -> Self {
|
||||
TemplateLoop {
|
||||
iter: iter.enumerate().peekable(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<I> Iterator for TemplateLoop<I>
|
||||
where
|
||||
I: Iterator,
|
||||
{
|
||||
type Item = (<I as Iterator>::Item, LoopItem);
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<(<I as Iterator>::Item, LoopItem)> {
|
||||
self.iter.next().map(|(index, item)| {
|
||||
(
|
||||
item,
|
||||
LoopItem {
|
||||
index,
|
||||
first: index == 0,
|
||||
last: self.iter.peek().is_none(),
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct LoopItem {
|
||||
pub index: usize,
|
||||
pub first: bool,
|
||||
pub last: bool,
|
||||
}
|
||||
219
third_party/rust/askama/src/lib.rs
vendored
Normal file
219
third_party/rust/askama/src/lib.rs
vendored
Normal file
@@ -0,0 +1,219 @@
|
||||
//! Askama implements a type-safe compiler for Jinja-like templates.
|
||||
//! It lets you write templates in a Jinja-like syntax,
|
||||
//! which are linked to a `struct` defining the template context.
|
||||
//! This is done using a custom derive implementation (implemented
|
||||
//! in [`askama_derive`](https://crates.io/crates/askama_derive)).
|
||||
//!
|
||||
//! For feature highlights and a quick start, please review the
|
||||
//! [README](https://github.com/djc/askama/blob/main/README.md).
|
||||
//!
|
||||
//! The primary documentation for this crate now lives in
|
||||
//! [the book](https://djc.github.io/askama/).
|
||||
//!
|
||||
//! # Creating Askama templates
|
||||
//!
|
||||
//! An Askama template is a `struct` definition which provides the template
|
||||
//! context combined with a UTF-8 encoded text file (or inline source, see
|
||||
//! below). Askama can be used to generate any kind of text-based format.
|
||||
//! The template file's extension may be used to provide content type hints.
|
||||
//!
|
||||
//! A template consists of **text contents**, which are passed through as-is,
|
||||
//! **expressions**, which get replaced with content while being rendered, and
|
||||
//! **tags**, which control the template's logic.
|
||||
//! The template syntax is very similar to [Jinja](http://jinja.pocoo.org/),
|
||||
//! as well as Jinja-derivatives like [Twig](http://twig.sensiolabs.org/) or
|
||||
//! [Tera](https://github.com/Keats/tera).
|
||||
//!
|
||||
//! ## The `template()` attribute
|
||||
//!
|
||||
//! Askama works by generating one or more trait implementations for any
|
||||
//! `struct` type decorated with the `#[derive(Template)]` attribute. The
|
||||
//! code generation process takes some options that can be specified through
|
||||
//! the `template()` attribute. The following sub-attributes are currently
|
||||
//! recognized:
|
||||
//!
|
||||
//! * `path` (as `path = "foo.html"`): sets the path to the template file. The
|
||||
//! path is interpreted as relative to the configured template directories
|
||||
//! (by default, this is a `templates` directory next to your `Cargo.toml`).
|
||||
//! The file name extension is used to infer an escape mode (see below). In
|
||||
//! web framework integrations, the path's extension may also be used to
|
||||
//! infer the content type of the resulting response.
|
||||
//! Cannot be used together with `source`.
|
||||
//! * `source` (as `source = "{{ foo }}"`): directly sets the template source.
|
||||
//! This can be useful for test cases or short templates. The generated path
|
||||
//! is undefined, which generally makes it impossible to refer to this
|
||||
//! template from other templates. If `source` is specified, `ext` must also
|
||||
//! be specified (see below). Cannot be used together with `path`.
|
||||
//! * `ext` (as `ext = "txt"`): lets you specify the content type as a file
|
||||
//! extension. This is used to infer an escape mode (see below), and some
|
||||
//! web framework integrations use it to determine the content type.
|
||||
//! Cannot be used together with `path`.
|
||||
//! * `print` (as `print = "code"`): enable debugging by printing nothing
|
||||
//! (`none`), the parsed syntax tree (`ast`), the generated code (`code`)
|
||||
//! or `all` for both. The requested data will be printed to stdout at
|
||||
//! compile time.
|
||||
//! * `escape` (as `escape = "none"`): override the template's extension used for
|
||||
//! the purpose of determining the escaper for this template. See the section
|
||||
//! on configuring custom escapers for more information.
|
||||
//! * `syntax` (as `syntax = "foo"`): set the syntax name for a parser defined
|
||||
//! in the configuration file. The default syntax , "default", is the one
|
||||
//! provided by Askama.
|
||||
|
||||
#![forbid(unsafe_code)]
|
||||
#![deny(elided_lifetimes_in_paths)]
|
||||
#![deny(unreachable_pub)]
|
||||
|
||||
mod error;
|
||||
pub mod filters;
|
||||
pub mod helpers;
|
||||
|
||||
use std::fmt;
|
||||
|
||||
pub use askama_derive::Template;
|
||||
pub use askama_escape::{Html, MarkupDisplay, Text};
|
||||
|
||||
#[doc(hidden)]
|
||||
pub use crate as shared;
|
||||
pub use crate::error::{Error, Result};
|
||||
|
||||
/// Main `Template` trait; implementations are generally derived
|
||||
///
|
||||
/// If you need an object-safe template, use [`DynTemplate`].
|
||||
pub trait Template: fmt::Display {
|
||||
/// Helper method which allocates a new `String` and renders into it
|
||||
fn render(&self) -> Result<String> {
|
||||
let mut buf = String::with_capacity(Self::SIZE_HINT);
|
||||
self.render_into(&mut buf)?;
|
||||
Ok(buf)
|
||||
}
|
||||
|
||||
/// Renders the template to the given `writer` fmt buffer
|
||||
fn render_into(&self, writer: &mut (impl std::fmt::Write + ?Sized)) -> Result<()>;
|
||||
|
||||
/// Renders the template to the given `writer` io buffer
|
||||
#[inline]
|
||||
fn write_into(&self, writer: &mut (impl std::io::Write + ?Sized)) -> std::io::Result<()> {
|
||||
writer.write_fmt(format_args!("{self}"))
|
||||
}
|
||||
|
||||
/// The template's extension, if provided
|
||||
const EXTENSION: Option<&'static str>;
|
||||
|
||||
/// Provides a conservative estimate of the expanded length of the rendered template
|
||||
const SIZE_HINT: usize;
|
||||
|
||||
/// The MIME type (Content-Type) of the data that gets rendered by this Template
|
||||
const MIME_TYPE: &'static str;
|
||||
}
|
||||
|
||||
/// Object-safe wrapper trait around [`Template`] implementers
|
||||
///
|
||||
/// This trades reduced performance (mostly due to writing into `dyn Write`) for object safety.
|
||||
pub trait DynTemplate {
|
||||
/// Helper method which allocates a new `String` and renders into it
|
||||
fn dyn_render(&self) -> Result<String>;
|
||||
|
||||
/// Renders the template to the given `writer` fmt buffer
|
||||
fn dyn_render_into(&self, writer: &mut dyn std::fmt::Write) -> Result<()>;
|
||||
|
||||
/// Renders the template to the given `writer` io buffer
|
||||
fn dyn_write_into(&self, writer: &mut dyn std::io::Write) -> std::io::Result<()>;
|
||||
|
||||
/// Helper function to inspect the template's extension
|
||||
fn extension(&self) -> Option<&'static str>;
|
||||
|
||||
/// Provides a conservative estimate of the expanded length of the rendered template
|
||||
fn size_hint(&self) -> usize;
|
||||
|
||||
/// The MIME type (Content-Type) of the data that gets rendered by this Template
|
||||
fn mime_type(&self) -> &'static str;
|
||||
}
|
||||
|
||||
impl<T: Template> DynTemplate for T {
|
||||
fn dyn_render(&self) -> Result<String> {
|
||||
<Self as Template>::render(self)
|
||||
}
|
||||
|
||||
fn dyn_render_into(&self, writer: &mut dyn std::fmt::Write) -> Result<()> {
|
||||
<Self as Template>::render_into(self, writer)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn dyn_write_into(&self, writer: &mut dyn std::io::Write) -> std::io::Result<()> {
|
||||
writer.write_fmt(format_args!("{self}"))
|
||||
}
|
||||
|
||||
fn extension(&self) -> Option<&'static str> {
|
||||
Self::EXTENSION
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> usize {
|
||||
Self::SIZE_HINT
|
||||
}
|
||||
|
||||
fn mime_type(&self) -> &'static str {
|
||||
Self::MIME_TYPE
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for dyn DynTemplate {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
self.dyn_render_into(f).map_err(|_| ::std::fmt::Error {})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::fmt;
|
||||
|
||||
use super::*;
|
||||
use crate::{DynTemplate, Template};
|
||||
|
||||
#[test]
|
||||
fn dyn_template() {
|
||||
struct Test;
|
||||
impl Template for Test {
|
||||
fn render_into(&self, writer: &mut (impl std::fmt::Write + ?Sized)) -> Result<()> {
|
||||
Ok(writer.write_str("test")?)
|
||||
}
|
||||
|
||||
const EXTENSION: Option<&'static str> = Some("txt");
|
||||
|
||||
const SIZE_HINT: usize = 4;
|
||||
|
||||
const MIME_TYPE: &'static str = "text/plain; charset=utf-8";
|
||||
}
|
||||
|
||||
impl fmt::Display for Test {
|
||||
#[inline]
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
self.render_into(f).map_err(|_| fmt::Error {})
|
||||
}
|
||||
}
|
||||
|
||||
fn render(t: &dyn DynTemplate) -> String {
|
||||
t.dyn_render().unwrap()
|
||||
}
|
||||
|
||||
let test = &Test as &dyn DynTemplate;
|
||||
|
||||
assert_eq!(render(test), "test");
|
||||
|
||||
assert_eq!(test.to_string(), "test");
|
||||
|
||||
assert_eq!(format!("{test}"), "test");
|
||||
|
||||
let mut vec = Vec::new();
|
||||
test.dyn_write_into(&mut vec).unwrap();
|
||||
assert_eq!(vec, vec![b't', b'e', b's', b't']);
|
||||
}
|
||||
}
|
||||
|
||||
/// Old build script helper to rebuild crates if contained templates have changed
|
||||
///
|
||||
/// This function is now deprecated and does nothing.
|
||||
#[deprecated(
|
||||
since = "0.8.1",
|
||||
note = "file-level dependency tracking is handled automatically without build script"
|
||||
)]
|
||||
pub fn rerun_if_templates_changed() {}
|
||||
1
third_party/rust/askama_derive/.cargo-checksum.json
vendored
Normal file
1
third_party/rust/askama_derive/.cargo-checksum.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"files":{"Cargo.toml":"f293fbc41371fb46f5b68775b158d8da37c09453dc9356ee8e97fce3d1021b2d","LICENSE-APACHE":"87cb0d734c723c083e51c825930ff42bce28596b52dee15567f6b28f19c195e3","LICENSE-MIT":"df20e0180764bf5bd76f74d47bc9e8c0069a666401629c390003a1d5eba99c92","README.md":"dd3e4e203eeca91219fd57c0ca1f92b413176f406df19568d0fe33d7905123e4","src/config.rs":"de4202804d32cc4da044ed41140ef987056f44116b1bbfac53001e07133e52b9","src/generator.rs":"4fec224dd261bc96a63b831f0692a62d9f8d19566377b39dd69bc0f3de4ab033","src/heritage.rs":"fceb0ac86034b8eb902212f9a78a6fb7d19688c3ccdb117099f15933073bf7bb","src/input.rs":"53afae3f73e2b52d83d73c1b38893677992a5ee04927e8b905198b742b1546ae","src/lib.rs":"003e91569575b72a9587796c82c9f9c0e5e9f3dc8db6b659735cf58f68504b76","src/parser/expr.rs":"3b8178398a293910df161ddd769d2efc7ae8dff03e7313f033149a38a6d81983","src/parser/mod.rs":"3afc065cdc69dc1498ddf9a04a77f56d807ed14653828918d36529a441fb6c48","src/parser/node.rs":"c5437e2525e245b6fcd358696f3607c50ef82cf649a66b6bef7816232c3220fa","src/parser/tests.rs":"81fb02f8cab87c93575fdb6b7d6e9cae6fa3b69173f5f5a76d214f5316ca66ca","templates/a.html":"b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c","templates/b.html":"7d865e959b2466918c9863afca942d0fb89d7c9ac0c99bafc3749504ded97730","templates/sub/b.html":"7d865e959b2466918c9863afca942d0fb89d7c9ac0c99bafc3749504ded97730","templates/sub/c.html":"bf07a7fbb825fc0aae7bf4a1177b2b31fcf8a3feeaf7092761e18c859ee52a9c","templates/sub/sub1/d.html":"86b0c5a1e2b73b08fd54c727f4458649ed9fe3ad1b6e8ac9460c070113509a1e"},"package":"c22fbe0413545c098358e56966ff22cdd039e10215ae213cfbd65032b119fc94"}
|
||||
72
third_party/rust/askama_derive/Cargo.toml
vendored
Normal file
72
third_party/rust/askama_derive/Cargo.toml
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
|
||||
#
|
||||
# When uploading crates to the registry Cargo will automatically
|
||||
# "normalize" Cargo.toml files for maximal compatibility
|
||||
# with all versions of Cargo and also rewrite `path` dependencies
|
||||
# to registry (e.g., crates.io) dependencies.
|
||||
#
|
||||
# If you are reading this file be aware that the original Cargo.toml
|
||||
# will likely look very different (and much more reasonable).
|
||||
# See Cargo.toml.orig for the original contents.
|
||||
|
||||
[package]
|
||||
edition = "2021"
|
||||
rust-version = "1.58"
|
||||
name = "askama_derive"
|
||||
version = "0.12.1"
|
||||
description = "Procedural macro package for Askama"
|
||||
homepage = "https://github.com/djc/askama"
|
||||
readme = "README.md"
|
||||
license = "MIT/Apache-2.0"
|
||||
repository = "https://github.com/djc/askama"
|
||||
resolver = "1"
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies.basic-toml]
|
||||
version = "0.1.1"
|
||||
optional = true
|
||||
|
||||
[dependencies.mime]
|
||||
version = "0.3"
|
||||
|
||||
[dependencies.mime_guess]
|
||||
version = "2"
|
||||
|
||||
[dependencies.nom]
|
||||
version = "7"
|
||||
|
||||
[dependencies.proc-macro2]
|
||||
version = "1"
|
||||
|
||||
[dependencies.quote]
|
||||
version = "1"
|
||||
|
||||
[dependencies.serde]
|
||||
version = "1.0"
|
||||
features = ["derive"]
|
||||
optional = true
|
||||
|
||||
[dependencies.syn]
|
||||
version = "2"
|
||||
|
||||
[features]
|
||||
config = [
|
||||
"serde",
|
||||
"basic-toml",
|
||||
]
|
||||
humansize = []
|
||||
markdown = []
|
||||
num-traits = []
|
||||
serde-json = []
|
||||
serde-yaml = []
|
||||
urlencode = []
|
||||
with-actix-web = []
|
||||
with-axum = []
|
||||
with-gotham = []
|
||||
with-hyper = []
|
||||
with-mendes = []
|
||||
with-rocket = []
|
||||
with-tide = []
|
||||
with-warp = []
|
||||
9
third_party/rust/askama_derive/README.md
vendored
Normal file
9
third_party/rust/askama_derive/README.md
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
# askama_derive: procedural macros for the Askama templating engine
|
||||
|
||||
[](https://docs.rs/askama_derive/)
|
||||
[](https://crates.io/crates/askama_derive)
|
||||
[](https://github.com/djc/askama/actions?query=workflow%3ACI)
|
||||
[](https://gitter.im/djc/askama)
|
||||
|
||||
This crate contains the procedural macros used by the
|
||||
[Askama](https://github.com/djc/askama) templating engine.
|
||||
582
third_party/rust/askama_derive/src/config.rs
vendored
Normal file
582
third_party/rust/askama_derive/src/config.rs
vendored
Normal file
@@ -0,0 +1,582 @@
|
||||
use std::collections::{BTreeMap, HashSet};
|
||||
use std::convert::TryFrom;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::{env, fs};
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::CompileError;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct Config<'a> {
|
||||
pub(crate) dirs: Vec<PathBuf>,
|
||||
pub(crate) syntaxes: BTreeMap<String, Syntax<'a>>,
|
||||
pub(crate) default_syntax: &'a str,
|
||||
pub(crate) escapers: Vec<(HashSet<String>, String)>,
|
||||
pub(crate) whitespace: WhitespaceHandling,
|
||||
}
|
||||
|
||||
impl<'a> Config<'a> {
|
||||
pub(crate) fn new(
|
||||
s: &'a str,
|
||||
template_whitespace: Option<&String>,
|
||||
) -> std::result::Result<Config<'a>, CompileError> {
|
||||
let root = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
|
||||
let default_dirs = vec![root.join("templates")];
|
||||
|
||||
let mut syntaxes = BTreeMap::new();
|
||||
syntaxes.insert(DEFAULT_SYNTAX_NAME.to_string(), Syntax::default());
|
||||
|
||||
let raw = if s.is_empty() {
|
||||
RawConfig::default()
|
||||
} else {
|
||||
RawConfig::from_toml_str(s)?
|
||||
};
|
||||
|
||||
let (dirs, default_syntax, mut whitespace) = match raw.general {
|
||||
Some(General {
|
||||
dirs,
|
||||
default_syntax,
|
||||
whitespace,
|
||||
}) => (
|
||||
dirs.map_or(default_dirs, |v| {
|
||||
v.into_iter().map(|dir| root.join(dir)).collect()
|
||||
}),
|
||||
default_syntax.unwrap_or(DEFAULT_SYNTAX_NAME),
|
||||
whitespace,
|
||||
),
|
||||
None => (
|
||||
default_dirs,
|
||||
DEFAULT_SYNTAX_NAME,
|
||||
WhitespaceHandling::default(),
|
||||
),
|
||||
};
|
||||
if let Some(template_whitespace) = template_whitespace {
|
||||
whitespace = match template_whitespace.as_str() {
|
||||
"suppress" => WhitespaceHandling::Suppress,
|
||||
"minimize" => WhitespaceHandling::Minimize,
|
||||
"preserve" => WhitespaceHandling::Preserve,
|
||||
s => return Err(format!("invalid value for `whitespace`: \"{s}\"").into()),
|
||||
};
|
||||
}
|
||||
|
||||
if let Some(raw_syntaxes) = raw.syntax {
|
||||
for raw_s in raw_syntaxes {
|
||||
let name = raw_s.name;
|
||||
|
||||
if syntaxes
|
||||
.insert(name.to_string(), Syntax::try_from(raw_s)?)
|
||||
.is_some()
|
||||
{
|
||||
return Err(format!("syntax \"{name}\" is already defined").into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !syntaxes.contains_key(default_syntax) {
|
||||
return Err(format!("default syntax \"{default_syntax}\" not found").into());
|
||||
}
|
||||
|
||||
let mut escapers = Vec::new();
|
||||
if let Some(configured) = raw.escaper {
|
||||
for escaper in configured {
|
||||
escapers.push((
|
||||
escaper
|
||||
.extensions
|
||||
.iter()
|
||||
.map(|ext| (*ext).to_string())
|
||||
.collect(),
|
||||
escaper.path.to_string(),
|
||||
));
|
||||
}
|
||||
}
|
||||
for (extensions, path) in DEFAULT_ESCAPERS {
|
||||
escapers.push((str_set(extensions), (*path).to_string()));
|
||||
}
|
||||
|
||||
Ok(Config {
|
||||
dirs,
|
||||
syntaxes,
|
||||
default_syntax,
|
||||
escapers,
|
||||
whitespace,
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn find_template(
|
||||
&self,
|
||||
path: &str,
|
||||
start_at: Option<&Path>,
|
||||
) -> std::result::Result<PathBuf, CompileError> {
|
||||
if let Some(root) = start_at {
|
||||
let relative = root.with_file_name(path);
|
||||
if relative.exists() {
|
||||
return Ok(relative);
|
||||
}
|
||||
}
|
||||
|
||||
for dir in &self.dirs {
|
||||
let rooted = dir.join(path);
|
||||
if rooted.exists() {
|
||||
return Ok(rooted);
|
||||
}
|
||||
}
|
||||
|
||||
Err(format!(
|
||||
"template {:?} not found in directories {:?}",
|
||||
path, self.dirs
|
||||
)
|
||||
.into())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct Syntax<'a> {
|
||||
pub(crate) block_start: &'a str,
|
||||
pub(crate) block_end: &'a str,
|
||||
pub(crate) expr_start: &'a str,
|
||||
pub(crate) expr_end: &'a str,
|
||||
pub(crate) comment_start: &'a str,
|
||||
pub(crate) comment_end: &'a str,
|
||||
}
|
||||
|
||||
impl Default for Syntax<'static> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
block_start: "{%",
|
||||
block_end: "%}",
|
||||
expr_start: "{{",
|
||||
expr_end: "}}",
|
||||
comment_start: "{#",
|
||||
comment_end: "#}",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TryFrom<RawSyntax<'a>> for Syntax<'a> {
|
||||
type Error = CompileError;
|
||||
|
||||
fn try_from(raw: RawSyntax<'a>) -> std::result::Result<Self, Self::Error> {
|
||||
let default = Syntax::default();
|
||||
let syntax = Self {
|
||||
block_start: raw.block_start.unwrap_or(default.block_start),
|
||||
block_end: raw.block_end.unwrap_or(default.block_end),
|
||||
expr_start: raw.expr_start.unwrap_or(default.expr_start),
|
||||
expr_end: raw.expr_end.unwrap_or(default.expr_end),
|
||||
comment_start: raw.comment_start.unwrap_or(default.comment_start),
|
||||
comment_end: raw.comment_end.unwrap_or(default.comment_end),
|
||||
};
|
||||
|
||||
if syntax.block_start.len() != 2
|
||||
|| syntax.block_end.len() != 2
|
||||
|| syntax.expr_start.len() != 2
|
||||
|| syntax.expr_end.len() != 2
|
||||
|| syntax.comment_start.len() != 2
|
||||
|| syntax.comment_end.len() != 2
|
||||
{
|
||||
return Err("length of delimiters must be two".into());
|
||||
}
|
||||
|
||||
let bs = syntax.block_start.as_bytes()[0];
|
||||
let be = syntax.block_start.as_bytes()[1];
|
||||
let cs = syntax.comment_start.as_bytes()[0];
|
||||
let ce = syntax.comment_start.as_bytes()[1];
|
||||
let es = syntax.expr_start.as_bytes()[0];
|
||||
let ee = syntax.expr_start.as_bytes()[1];
|
||||
if !((bs == cs && bs == es) || (be == ce && be == ee)) {
|
||||
return Err(format!("bad delimiters block_start: {}, comment_start: {}, expr_start: {}, needs one of the two characters in common", syntax.block_start, syntax.comment_start, syntax.expr_start).into());
|
||||
}
|
||||
|
||||
Ok(syntax)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "serde", derive(Deserialize))]
|
||||
#[derive(Default)]
|
||||
struct RawConfig<'a> {
|
||||
#[cfg_attr(feature = "serde", serde(borrow))]
|
||||
general: Option<General<'a>>,
|
||||
syntax: Option<Vec<RawSyntax<'a>>>,
|
||||
escaper: Option<Vec<RawEscaper<'a>>>,
|
||||
}
|
||||
|
||||
impl RawConfig<'_> {
|
||||
#[cfg(feature = "config")]
|
||||
fn from_toml_str(s: &str) -> std::result::Result<RawConfig<'_>, CompileError> {
|
||||
basic_toml::from_str(s)
|
||||
.map_err(|e| format!("invalid TOML in {CONFIG_FILE_NAME}: {e}").into())
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "config"))]
|
||||
fn from_toml_str(_: &str) -> std::result::Result<RawConfig<'_>, CompileError> {
|
||||
Err("TOML support not available".into())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(field_identifier, rename_all = "lowercase"))]
|
||||
pub(crate) enum WhitespaceHandling {
|
||||
/// The default behaviour. It will leave the whitespace characters "as is".
|
||||
Preserve,
|
||||
/// It'll remove all the whitespace characters before and after the jinja block.
|
||||
Suppress,
|
||||
/// It'll remove all the whitespace characters except one before and after the jinja blocks.
|
||||
/// If there is a newline character, the preserved character in the trimmed characters, it will
|
||||
/// the one preserved.
|
||||
Minimize,
|
||||
}
|
||||
|
||||
impl Default for WhitespaceHandling {
|
||||
fn default() -> Self {
|
||||
WhitespaceHandling::Preserve
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "serde", derive(Deserialize))]
|
||||
struct General<'a> {
|
||||
#[cfg_attr(feature = "serde", serde(borrow))]
|
||||
dirs: Option<Vec<&'a str>>,
|
||||
default_syntax: Option<&'a str>,
|
||||
#[cfg_attr(feature = "serde", serde(default))]
|
||||
whitespace: WhitespaceHandling,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "serde", derive(Deserialize))]
|
||||
struct RawSyntax<'a> {
|
||||
name: &'a str,
|
||||
block_start: Option<&'a str>,
|
||||
block_end: Option<&'a str>,
|
||||
expr_start: Option<&'a str>,
|
||||
expr_end: Option<&'a str>,
|
||||
comment_start: Option<&'a str>,
|
||||
comment_end: Option<&'a str>,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "serde", derive(Deserialize))]
|
||||
struct RawEscaper<'a> {
|
||||
path: &'a str,
|
||||
extensions: Vec<&'a str>,
|
||||
}
|
||||
|
||||
pub(crate) fn read_config_file(
|
||||
config_path: Option<&str>,
|
||||
) -> std::result::Result<String, CompileError> {
|
||||
let root = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
|
||||
let filename = match config_path {
|
||||
Some(config_path) => root.join(config_path),
|
||||
None => root.join(CONFIG_FILE_NAME),
|
||||
};
|
||||
|
||||
if filename.exists() {
|
||||
fs::read_to_string(&filename)
|
||||
.map_err(|_| format!("unable to read {:?}", filename.to_str().unwrap()).into())
|
||||
} else if config_path.is_some() {
|
||||
Err(format!("`{}` does not exist", root.display()).into())
|
||||
} else {
|
||||
Ok("".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
fn str_set<T>(vals: &[T]) -> HashSet<String>
|
||||
where
|
||||
T: ToString,
|
||||
{
|
||||
vals.iter().map(|s| s.to_string()).collect()
|
||||
}
|
||||
|
||||
#[allow(clippy::match_wild_err_arm)]
|
||||
pub(crate) fn get_template_source(tpl_path: &Path) -> std::result::Result<String, CompileError> {
|
||||
match fs::read_to_string(tpl_path) {
|
||||
Err(_) => Err(format!(
|
||||
"unable to open template file '{}'",
|
||||
tpl_path.to_str().unwrap()
|
||||
)
|
||||
.into()),
|
||||
Ok(mut source) => {
|
||||
if source.ends_with('\n') {
|
||||
let _ = source.pop();
|
||||
}
|
||||
Ok(source)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static CONFIG_FILE_NAME: &str = "askama.toml";
|
||||
static DEFAULT_SYNTAX_NAME: &str = "default";
|
||||
static DEFAULT_ESCAPERS: &[(&[&str], &str)] = &[
|
||||
(&["html", "htm", "xml"], "::askama::Html"),
|
||||
(&["md", "none", "txt", "yml", ""], "::askama::Text"),
|
||||
(&["j2", "jinja", "jinja2"], "::askama::Html"),
|
||||
];
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::env;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn get_source() {
|
||||
let path = Config::new("", None)
|
||||
.and_then(|config| config.find_template("b.html", None))
|
||||
.unwrap();
|
||||
assert_eq!(get_template_source(&path).unwrap(), "bar");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_default_config() {
|
||||
let mut root = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
|
||||
root.push("templates");
|
||||
let config = Config::new("", None).unwrap();
|
||||
assert_eq!(config.dirs, vec![root]);
|
||||
}
|
||||
|
||||
#[cfg(feature = "config")]
|
||||
#[test]
|
||||
fn test_config_dirs() {
|
||||
let mut root = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
|
||||
root.push("tpl");
|
||||
let config = Config::new("[general]\ndirs = [\"tpl\"]", None).unwrap();
|
||||
assert_eq!(config.dirs, vec![root]);
|
||||
}
|
||||
|
||||
fn assert_eq_rooted(actual: &Path, expected: &str) {
|
||||
let mut root = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
|
||||
root.push("templates");
|
||||
let mut inner = PathBuf::new();
|
||||
inner.push(expected);
|
||||
assert_eq!(actual.strip_prefix(root).unwrap(), inner);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn find_absolute() {
|
||||
let config = Config::new("", None).unwrap();
|
||||
let root = config.find_template("a.html", None).unwrap();
|
||||
let path = config.find_template("sub/b.html", Some(&root)).unwrap();
|
||||
assert_eq_rooted(&path, "sub/b.html");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn find_relative_nonexistent() {
|
||||
let config = Config::new("", None).unwrap();
|
||||
let root = config.find_template("a.html", None).unwrap();
|
||||
config.find_template("c.html", Some(&root)).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn find_relative() {
|
||||
let config = Config::new("", None).unwrap();
|
||||
let root = config.find_template("sub/b.html", None).unwrap();
|
||||
let path = config.find_template("c.html", Some(&root)).unwrap();
|
||||
assert_eq_rooted(&path, "sub/c.html");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn find_relative_sub() {
|
||||
let config = Config::new("", None).unwrap();
|
||||
let root = config.find_template("sub/b.html", None).unwrap();
|
||||
let path = config.find_template("sub1/d.html", Some(&root)).unwrap();
|
||||
assert_eq_rooted(&path, "sub/sub1/d.html");
|
||||
}
|
||||
|
||||
#[cfg(feature = "config")]
|
||||
#[test]
|
||||
fn add_syntax() {
|
||||
let raw_config = r#"
|
||||
[general]
|
||||
default_syntax = "foo"
|
||||
|
||||
[[syntax]]
|
||||
name = "foo"
|
||||
block_start = "{<"
|
||||
|
||||
[[syntax]]
|
||||
name = "bar"
|
||||
expr_start = "{!"
|
||||
"#;
|
||||
|
||||
let default_syntax = Syntax::default();
|
||||
let config = Config::new(raw_config, None).unwrap();
|
||||
assert_eq!(config.default_syntax, "foo");
|
||||
|
||||
let foo = config.syntaxes.get("foo").unwrap();
|
||||
assert_eq!(foo.block_start, "{<");
|
||||
assert_eq!(foo.block_end, default_syntax.block_end);
|
||||
assert_eq!(foo.expr_start, default_syntax.expr_start);
|
||||
assert_eq!(foo.expr_end, default_syntax.expr_end);
|
||||
assert_eq!(foo.comment_start, default_syntax.comment_start);
|
||||
assert_eq!(foo.comment_end, default_syntax.comment_end);
|
||||
|
||||
let bar = config.syntaxes.get("bar").unwrap();
|
||||
assert_eq!(bar.block_start, default_syntax.block_start);
|
||||
assert_eq!(bar.block_end, default_syntax.block_end);
|
||||
assert_eq!(bar.expr_start, "{!");
|
||||
assert_eq!(bar.expr_end, default_syntax.expr_end);
|
||||
assert_eq!(bar.comment_start, default_syntax.comment_start);
|
||||
assert_eq!(bar.comment_end, default_syntax.comment_end);
|
||||
}
|
||||
|
||||
#[cfg(feature = "config")]
|
||||
#[test]
|
||||
fn add_syntax_two() {
|
||||
let raw_config = r#"
|
||||
syntax = [{ name = "foo", block_start = "{<" },
|
||||
{ name = "bar", expr_start = "{!" } ]
|
||||
|
||||
[general]
|
||||
default_syntax = "foo"
|
||||
"#;
|
||||
|
||||
let default_syntax = Syntax::default();
|
||||
let config = Config::new(raw_config, None).unwrap();
|
||||
assert_eq!(config.default_syntax, "foo");
|
||||
|
||||
let foo = config.syntaxes.get("foo").unwrap();
|
||||
assert_eq!(foo.block_start, "{<");
|
||||
assert_eq!(foo.block_end, default_syntax.block_end);
|
||||
assert_eq!(foo.expr_start, default_syntax.expr_start);
|
||||
assert_eq!(foo.expr_end, default_syntax.expr_end);
|
||||
assert_eq!(foo.comment_start, default_syntax.comment_start);
|
||||
assert_eq!(foo.comment_end, default_syntax.comment_end);
|
||||
|
||||
let bar = config.syntaxes.get("bar").unwrap();
|
||||
assert_eq!(bar.block_start, default_syntax.block_start);
|
||||
assert_eq!(bar.block_end, default_syntax.block_end);
|
||||
assert_eq!(bar.expr_start, "{!");
|
||||
assert_eq!(bar.expr_end, default_syntax.expr_end);
|
||||
assert_eq!(bar.comment_start, default_syntax.comment_start);
|
||||
assert_eq!(bar.comment_end, default_syntax.comment_end);
|
||||
}
|
||||
|
||||
#[cfg(feature = "toml")]
|
||||
#[should_panic]
|
||||
#[test]
|
||||
fn use_default_at_syntax_name() {
|
||||
let raw_config = r#"
|
||||
syntax = [{ name = "default" }]
|
||||
"#;
|
||||
|
||||
let _config = Config::new(raw_config, None).unwrap();
|
||||
}
|
||||
|
||||
#[cfg(feature = "toml")]
|
||||
#[should_panic]
|
||||
#[test]
|
||||
fn duplicated_syntax_name_on_list() {
|
||||
let raw_config = r#"
|
||||
syntax = [{ name = "foo", block_start = "~<" },
|
||||
{ name = "foo", block_start = "%%" } ]
|
||||
"#;
|
||||
|
||||
let _config = Config::new(raw_config, None).unwrap();
|
||||
}
|
||||
|
||||
#[cfg(feature = "toml")]
|
||||
#[should_panic]
|
||||
#[test]
|
||||
fn is_not_exist_default_syntax() {
|
||||
let raw_config = r#"
|
||||
[general]
|
||||
default_syntax = "foo"
|
||||
"#;
|
||||
|
||||
let _config = Config::new(raw_config, None).unwrap();
|
||||
}
|
||||
|
||||
#[cfg(feature = "config")]
|
||||
#[test]
|
||||
fn escape_modes() {
|
||||
let config = Config::new(
|
||||
r#"
|
||||
[[escaper]]
|
||||
path = "::askama::Js"
|
||||
extensions = ["js"]
|
||||
"#,
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
config.escapers,
|
||||
vec![
|
||||
(str_set(&["js"]), "::askama::Js".into()),
|
||||
(str_set(&["html", "htm", "xml"]), "::askama::Html".into()),
|
||||
(
|
||||
str_set(&["md", "none", "txt", "yml", ""]),
|
||||
"::askama::Text".into()
|
||||
),
|
||||
(str_set(&["j2", "jinja", "jinja2"]), "::askama::Html".into()),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "config")]
|
||||
#[test]
|
||||
fn test_whitespace_parsing() {
|
||||
let config = Config::new(
|
||||
r#"
|
||||
[general]
|
||||
whitespace = "suppress"
|
||||
"#,
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(config.whitespace, WhitespaceHandling::Suppress);
|
||||
|
||||
let config = Config::new(r#""#, None).unwrap();
|
||||
assert_eq!(config.whitespace, WhitespaceHandling::Preserve);
|
||||
|
||||
let config = Config::new(
|
||||
r#"
|
||||
[general]
|
||||
whitespace = "preserve"
|
||||
"#,
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(config.whitespace, WhitespaceHandling::Preserve);
|
||||
|
||||
let config = Config::new(
|
||||
r#"
|
||||
[general]
|
||||
whitespace = "minimize"
|
||||
"#,
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(config.whitespace, WhitespaceHandling::Minimize);
|
||||
}
|
||||
|
||||
#[cfg(feature = "toml")]
|
||||
#[test]
|
||||
fn test_whitespace_in_template() {
|
||||
// Checking that template arguments have precedence over general configuration.
|
||||
// So in here, in the template arguments, there is `whitespace = "minimize"` so
|
||||
// the `WhitespaceHandling` should be `Minimize` as well.
|
||||
let config = Config::new(
|
||||
r#"
|
||||
[general]
|
||||
whitespace = "suppress"
|
||||
"#,
|
||||
Some(&"minimize".to_owned()),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(config.whitespace, WhitespaceHandling::Minimize);
|
||||
|
||||
let config = Config::new(r#""#, Some(&"minimize".to_owned())).unwrap();
|
||||
assert_eq!(config.whitespace, WhitespaceHandling::Minimize);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_config_whitespace_error() {
|
||||
let config = Config::new(r#""#, Some(&"trim".to_owned()));
|
||||
if let Err(err) = config {
|
||||
assert_eq!(err.msg, "invalid value for `whitespace`: \"trim\"");
|
||||
} else {
|
||||
panic!("Config::new should have return an error");
|
||||
}
|
||||
}
|
||||
}
|
||||
2171
third_party/rust/askama_derive/src/generator.rs
vendored
Normal file
2171
third_party/rust/askama_derive/src/generator.rs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
126
third_party/rust/askama_derive/src/heritage.rs
vendored
Normal file
126
third_party/rust/askama_derive/src/heritage.rs
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
use std::collections::HashMap;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use crate::config::Config;
|
||||
use crate::parser::{Loop, Macro, Node};
|
||||
use crate::CompileError;
|
||||
|
||||
pub(crate) struct Heritage<'a> {
|
||||
pub(crate) root: &'a Context<'a>,
|
||||
pub(crate) blocks: BlockAncestry<'a>,
|
||||
}
|
||||
|
||||
impl Heritage<'_> {
|
||||
pub(crate) fn new<'n>(
|
||||
mut ctx: &'n Context<'n>,
|
||||
contexts: &'n HashMap<&'n Path, Context<'n>>,
|
||||
) -> Heritage<'n> {
|
||||
let mut blocks: BlockAncestry<'n> = ctx
|
||||
.blocks
|
||||
.iter()
|
||||
.map(|(name, def)| (*name, vec![(ctx, *def)]))
|
||||
.collect();
|
||||
|
||||
while let Some(ref path) = ctx.extends {
|
||||
ctx = &contexts[path.as_path()];
|
||||
for (name, def) in &ctx.blocks {
|
||||
blocks.entry(name).or_insert_with(Vec::new).push((ctx, def));
|
||||
}
|
||||
}
|
||||
|
||||
Heritage { root: ctx, blocks }
|
||||
}
|
||||
}
|
||||
|
||||
type BlockAncestry<'a> = HashMap<&'a str, Vec<(&'a Context<'a>, &'a Node<'a>)>>;
|
||||
|
||||
pub(crate) struct Context<'a> {
|
||||
pub(crate) nodes: &'a [Node<'a>],
|
||||
pub(crate) extends: Option<PathBuf>,
|
||||
pub(crate) blocks: HashMap<&'a str, &'a Node<'a>>,
|
||||
pub(crate) macros: HashMap<&'a str, &'a Macro<'a>>,
|
||||
pub(crate) imports: HashMap<&'a str, PathBuf>,
|
||||
}
|
||||
|
||||
impl Context<'_> {
|
||||
pub(crate) fn new<'n>(
|
||||
config: &Config<'_>,
|
||||
path: &Path,
|
||||
nodes: &'n [Node<'n>],
|
||||
) -> Result<Context<'n>, CompileError> {
|
||||
let mut extends = None;
|
||||
let mut blocks = Vec::new();
|
||||
let mut macros = HashMap::new();
|
||||
let mut imports = HashMap::new();
|
||||
let mut nested = vec![nodes];
|
||||
let mut top = true;
|
||||
|
||||
while let Some(nodes) = nested.pop() {
|
||||
for n in nodes {
|
||||
match n {
|
||||
Node::Extends(extends_path) if top => match extends {
|
||||
Some(_) => return Err("multiple extend blocks found".into()),
|
||||
None => {
|
||||
extends = Some(config.find_template(extends_path, Some(path))?);
|
||||
}
|
||||
},
|
||||
Node::Macro(name, m) if top => {
|
||||
macros.insert(*name, m);
|
||||
}
|
||||
Node::Import(_, import_path, scope) if top => {
|
||||
let path = config.find_template(import_path, Some(path))?;
|
||||
imports.insert(*scope, path);
|
||||
}
|
||||
Node::Extends(_) | Node::Macro(_, _) | Node::Import(_, _, _) if !top => {
|
||||
return Err(
|
||||
"extends, macro or import blocks not allowed below top level".into(),
|
||||
);
|
||||
}
|
||||
def @ Node::BlockDef(_, _, _, _) => {
|
||||
blocks.push(def);
|
||||
if let Node::BlockDef(_, _, nodes, _) = def {
|
||||
nested.push(nodes);
|
||||
}
|
||||
}
|
||||
Node::Cond(branches, _) => {
|
||||
for (_, _, nodes) in branches {
|
||||
nested.push(nodes);
|
||||
}
|
||||
}
|
||||
Node::Loop(Loop {
|
||||
body, else_block, ..
|
||||
}) => {
|
||||
nested.push(body);
|
||||
nested.push(else_block);
|
||||
}
|
||||
Node::Match(_, _, arms, _) => {
|
||||
for (_, _, arm) in arms {
|
||||
nested.push(arm);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
top = false;
|
||||
}
|
||||
|
||||
let blocks: HashMap<_, _> = blocks
|
||||
.iter()
|
||||
.map(|def| {
|
||||
if let Node::BlockDef(_, name, _, _) = def {
|
||||
(*name, *def)
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
Ok(Context {
|
||||
nodes,
|
||||
extends,
|
||||
blocks,
|
||||
macros,
|
||||
imports,
|
||||
})
|
||||
}
|
||||
}
|
||||
231
third_party/rust/askama_derive/src/input.rs
vendored
Normal file
231
third_party/rust/askama_derive/src/input.rs
vendored
Normal file
@@ -0,0 +1,231 @@
|
||||
use crate::config::{Config, Syntax};
|
||||
use crate::generator::TemplateArgs;
|
||||
use crate::CompileError;
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::str::FromStr;
|
||||
|
||||
use mime::Mime;
|
||||
|
||||
pub(crate) struct TemplateInput<'a> {
|
||||
pub(crate) ast: &'a syn::DeriveInput,
|
||||
pub(crate) config: &'a Config<'a>,
|
||||
pub(crate) syntax: &'a Syntax<'a>,
|
||||
pub(crate) source: Source,
|
||||
pub(crate) print: Print,
|
||||
pub(crate) escaper: &'a str,
|
||||
pub(crate) ext: Option<String>,
|
||||
pub(crate) mime_type: String,
|
||||
pub(crate) path: PathBuf,
|
||||
}
|
||||
|
||||
impl TemplateInput<'_> {
|
||||
/// Extract the template metadata from the `DeriveInput` structure. This
|
||||
/// mostly recovers the data for the `TemplateInput` fields from the
|
||||
/// `template()` attribute list fields.
|
||||
pub(crate) fn new<'n>(
|
||||
ast: &'n syn::DeriveInput,
|
||||
config: &'n Config<'_>,
|
||||
args: TemplateArgs,
|
||||
) -> Result<TemplateInput<'n>, CompileError> {
|
||||
let TemplateArgs {
|
||||
source,
|
||||
print,
|
||||
escaping,
|
||||
ext,
|
||||
syntax,
|
||||
..
|
||||
} = args;
|
||||
|
||||
// Validate the `source` and `ext` value together, since they are
|
||||
// related. In case `source` was used instead of `path`, the value
|
||||
// of `ext` is merged into a synthetic `path` value here.
|
||||
let source = source.expect("template path or source not found in attributes");
|
||||
let path = match (&source, &ext) {
|
||||
(Source::Path(path), _) => config.find_template(path, None)?,
|
||||
(&Source::Source(_), Some(ext)) => PathBuf::from(format!("{}.{}", ast.ident, ext)),
|
||||
(&Source::Source(_), None) => {
|
||||
return Err("must include 'ext' attribute when using 'source' attribute".into())
|
||||
}
|
||||
};
|
||||
|
||||
// Validate syntax
|
||||
let syntax = syntax.map_or_else(
|
||||
|| Ok(config.syntaxes.get(config.default_syntax).unwrap()),
|
||||
|s| {
|
||||
config
|
||||
.syntaxes
|
||||
.get(&s)
|
||||
.ok_or_else(|| CompileError::from(format!("attribute syntax {s} not exist")))
|
||||
},
|
||||
)?;
|
||||
|
||||
// Match extension against defined output formats
|
||||
|
||||
let escaping = escaping.unwrap_or_else(|| {
|
||||
path.extension()
|
||||
.map(|s| s.to_str().unwrap())
|
||||
.unwrap_or("")
|
||||
.to_string()
|
||||
});
|
||||
|
||||
let mut escaper = None;
|
||||
for (extensions, path) in &config.escapers {
|
||||
if extensions.contains(&escaping) {
|
||||
escaper = Some(path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let escaper = escaper.ok_or_else(|| {
|
||||
CompileError::from(format!("no escaper defined for extension '{escaping}'"))
|
||||
})?;
|
||||
|
||||
let mime_type =
|
||||
extension_to_mime_type(ext_default_to_path(ext.as_deref(), &path).unwrap_or("txt"))
|
||||
.to_string();
|
||||
|
||||
Ok(TemplateInput {
|
||||
ast,
|
||||
config,
|
||||
syntax,
|
||||
source,
|
||||
print,
|
||||
escaper,
|
||||
ext,
|
||||
mime_type,
|
||||
path,
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn extension(&self) -> Option<&str> {
|
||||
ext_default_to_path(self.ext.as_deref(), &self.path)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn ext_default_to_path<'a>(ext: Option<&'a str>, path: &'a Path) -> Option<&'a str> {
|
||||
ext.or_else(|| extension(path))
|
||||
}
|
||||
|
||||
fn extension(path: &Path) -> Option<&str> {
|
||||
let ext = path.extension().map(|s| s.to_str().unwrap())?;
|
||||
|
||||
const JINJA_EXTENSIONS: [&str; 3] = ["j2", "jinja", "jinja2"];
|
||||
if JINJA_EXTENSIONS.contains(&ext) {
|
||||
Path::new(path.file_stem().unwrap())
|
||||
.extension()
|
||||
.map(|s| s.to_str().unwrap())
|
||||
.or(Some(ext))
|
||||
} else {
|
||||
Some(ext)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) enum Source {
|
||||
Path(String),
|
||||
Source(String),
|
||||
}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
pub(crate) enum Print {
|
||||
All,
|
||||
Ast,
|
||||
Code,
|
||||
None,
|
||||
}
|
||||
|
||||
impl FromStr for Print {
|
||||
type Err = CompileError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Print, Self::Err> {
|
||||
use self::Print::*;
|
||||
Ok(match s {
|
||||
"all" => All,
|
||||
"ast" => Ast,
|
||||
"code" => Code,
|
||||
"none" => None,
|
||||
v => return Err(format!("invalid value for print option: {v}",).into()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Print {
|
||||
fn default() -> Self {
|
||||
Self::None
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn extension_to_mime_type(ext: &str) -> Mime {
|
||||
let basic_type = mime_guess::from_ext(ext).first_or_octet_stream();
|
||||
for (simple, utf_8) in &TEXT_TYPES {
|
||||
if &basic_type == simple {
|
||||
return utf_8.clone();
|
||||
}
|
||||
}
|
||||
basic_type
|
||||
}
|
||||
|
||||
const TEXT_TYPES: [(Mime, Mime); 6] = [
|
||||
(mime::TEXT_PLAIN, mime::TEXT_PLAIN_UTF_8),
|
||||
(mime::TEXT_HTML, mime::TEXT_HTML_UTF_8),
|
||||
(mime::TEXT_CSS, mime::TEXT_CSS_UTF_8),
|
||||
(mime::TEXT_CSV, mime::TEXT_CSV_UTF_8),
|
||||
(
|
||||
mime::TEXT_TAB_SEPARATED_VALUES,
|
||||
mime::TEXT_TAB_SEPARATED_VALUES_UTF_8,
|
||||
),
|
||||
(
|
||||
mime::APPLICATION_JAVASCRIPT,
|
||||
mime::APPLICATION_JAVASCRIPT_UTF_8,
|
||||
),
|
||||
];
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_ext() {
|
||||
assert_eq!(extension(Path::new("foo-bar.txt")), Some("txt"));
|
||||
assert_eq!(extension(Path::new("foo-bar.html")), Some("html"));
|
||||
assert_eq!(extension(Path::new("foo-bar.unknown")), Some("unknown"));
|
||||
|
||||
assert_eq!(extension(Path::new("foo/bar/baz.txt")), Some("txt"));
|
||||
assert_eq!(extension(Path::new("foo/bar/baz.html")), Some("html"));
|
||||
assert_eq!(extension(Path::new("foo/bar/baz.unknown")), Some("unknown"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_double_ext() {
|
||||
assert_eq!(extension(Path::new("foo-bar.html.txt")), Some("txt"));
|
||||
assert_eq!(extension(Path::new("foo-bar.txt.html")), Some("html"));
|
||||
assert_eq!(extension(Path::new("foo-bar.txt.unknown")), Some("unknown"));
|
||||
|
||||
assert_eq!(extension(Path::new("foo/bar/baz.html.txt")), Some("txt"));
|
||||
assert_eq!(extension(Path::new("foo/bar/baz.txt.html")), Some("html"));
|
||||
assert_eq!(
|
||||
extension(Path::new("foo/bar/baz.txt.unknown")),
|
||||
Some("unknown")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_skip_jinja_ext() {
|
||||
assert_eq!(extension(Path::new("foo-bar.html.j2")), Some("html"));
|
||||
assert_eq!(extension(Path::new("foo-bar.html.jinja")), Some("html"));
|
||||
assert_eq!(extension(Path::new("foo-bar.html.jinja2")), Some("html"));
|
||||
|
||||
assert_eq!(extension(Path::new("foo/bar/baz.txt.j2")), Some("txt"));
|
||||
assert_eq!(extension(Path::new("foo/bar/baz.txt.jinja")), Some("txt"));
|
||||
assert_eq!(extension(Path::new("foo/bar/baz.txt.jinja2")), Some("txt"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_only_jinja_ext() {
|
||||
assert_eq!(extension(Path::new("foo-bar.j2")), Some("j2"));
|
||||
assert_eq!(extension(Path::new("foo-bar.jinja")), Some("jinja"));
|
||||
assert_eq!(extension(Path::new("foo-bar.jinja2")), Some("jinja2"));
|
||||
}
|
||||
}
|
||||
100
third_party/rust/askama_derive/src/lib.rs
vendored
Normal file
100
third_party/rust/askama_derive/src/lib.rs
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
#![forbid(unsafe_code)]
|
||||
#![deny(elided_lifetimes_in_paths)]
|
||||
#![deny(unreachable_pub)]
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::fmt;
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
use proc_macro2::Span;
|
||||
|
||||
mod config;
|
||||
mod generator;
|
||||
mod heritage;
|
||||
mod input;
|
||||
mod parser;
|
||||
|
||||
#[proc_macro_derive(Template, attributes(template))]
|
||||
pub fn derive_template(input: TokenStream) -> TokenStream {
|
||||
generator::derive_template(input)
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct CompileError {
|
||||
msg: Cow<'static, str>,
|
||||
span: Span,
|
||||
}
|
||||
|
||||
impl CompileError {
|
||||
fn new<S: Into<Cow<'static, str>>>(s: S, span: Span) -> Self {
|
||||
Self {
|
||||
msg: s.into(),
|
||||
span,
|
||||
}
|
||||
}
|
||||
|
||||
fn into_compile_error(self) -> TokenStream {
|
||||
syn::Error::new(self.span, self.msg)
|
||||
.to_compile_error()
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for CompileError {}
|
||||
|
||||
impl fmt::Display for CompileError {
|
||||
#[inline]
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fmt.write_str(&self.msg)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&'static str> for CompileError {
|
||||
#[inline]
|
||||
fn from(s: &'static str) -> Self {
|
||||
Self::new(s, Span::call_site())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for CompileError {
|
||||
#[inline]
|
||||
fn from(s: String) -> Self {
|
||||
Self::new(s, Span::call_site())
|
||||
}
|
||||
}
|
||||
|
||||
// This is used by the code generator to decide whether a named filter is part of
|
||||
// Askama or should refer to a local `filters` module. It should contain all the
|
||||
// filters shipped with Askama, even the optional ones (since optional inclusion
|
||||
// in the const vector based on features seems impossible right now).
|
||||
const BUILT_IN_FILTERS: &[&str] = &[
|
||||
"abs",
|
||||
"capitalize",
|
||||
"center",
|
||||
"e",
|
||||
"escape",
|
||||
"filesizeformat",
|
||||
"fmt",
|
||||
"format",
|
||||
"indent",
|
||||
"into_f64",
|
||||
"into_isize",
|
||||
"join",
|
||||
"linebreaks",
|
||||
"linebreaksbr",
|
||||
"paragraphbreaks",
|
||||
"lower",
|
||||
"lowercase",
|
||||
"safe",
|
||||
"trim",
|
||||
"truncate",
|
||||
"upper",
|
||||
"uppercase",
|
||||
"urlencode",
|
||||
"urlencode_strict",
|
||||
"wordcount",
|
||||
// optional features, reserve the names anyway:
|
||||
"json",
|
||||
"markdown",
|
||||
"yaml",
|
||||
];
|
||||
346
third_party/rust/askama_derive/src/parser/expr.rs
vendored
Normal file
346
third_party/rust/askama_derive/src/parser/expr.rs
vendored
Normal file
@@ -0,0 +1,346 @@
|
||||
use std::str;
|
||||
|
||||
use nom::branch::alt;
|
||||
use nom::bytes::complete::{tag, take_till};
|
||||
use nom::character::complete::char;
|
||||
use nom::combinator::{cut, map, not, opt, peek, recognize};
|
||||
use nom::multi::{fold_many0, many0, separated_list0, separated_list1};
|
||||
use nom::sequence::{delimited, pair, preceded, terminated, tuple};
|
||||
use nom::IResult;
|
||||
|
||||
use super::{
|
||||
bool_lit, char_lit, identifier, nested_parenthesis, not_ws, num_lit, path, str_lit, ws,
|
||||
};
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub(crate) enum Expr<'a> {
|
||||
BoolLit(&'a str),
|
||||
NumLit(&'a str),
|
||||
StrLit(&'a str),
|
||||
CharLit(&'a str),
|
||||
Var(&'a str),
|
||||
Path(Vec<&'a str>),
|
||||
Array(Vec<Expr<'a>>),
|
||||
Attr(Box<Expr<'a>>, &'a str),
|
||||
Index(Box<Expr<'a>>, Box<Expr<'a>>),
|
||||
Filter(&'a str, Vec<Expr<'a>>),
|
||||
Unary(&'a str, Box<Expr<'a>>),
|
||||
BinOp(&'a str, Box<Expr<'a>>, Box<Expr<'a>>),
|
||||
Range(&'a str, Option<Box<Expr<'a>>>, Option<Box<Expr<'a>>>),
|
||||
Group(Box<Expr<'a>>),
|
||||
Tuple(Vec<Expr<'a>>),
|
||||
Call(Box<Expr<'a>>, Vec<Expr<'a>>),
|
||||
RustMacro(&'a str, &'a str),
|
||||
Try(Box<Expr<'a>>),
|
||||
}
|
||||
|
||||
impl Expr<'_> {
|
||||
pub(super) fn parse(i: &str) -> IResult<&str, Expr<'_>> {
|
||||
expr_any(i)
|
||||
}
|
||||
|
||||
pub(super) fn parse_arguments(i: &str) -> IResult<&str, Vec<Expr<'_>>> {
|
||||
arguments(i)
|
||||
}
|
||||
|
||||
/// Returns `true` if enough assumptions can be made,
|
||||
/// to determine that `self` is copyable.
|
||||
pub(crate) fn is_copyable(&self) -> bool {
|
||||
self.is_copyable_within_op(false)
|
||||
}
|
||||
|
||||
fn is_copyable_within_op(&self, within_op: bool) -> bool {
|
||||
use Expr::*;
|
||||
match self {
|
||||
BoolLit(_) | NumLit(_) | StrLit(_) | CharLit(_) => true,
|
||||
Unary(.., expr) => expr.is_copyable_within_op(true),
|
||||
BinOp(_, lhs, rhs) => {
|
||||
lhs.is_copyable_within_op(true) && rhs.is_copyable_within_op(true)
|
||||
}
|
||||
Range(..) => true,
|
||||
// The result of a call likely doesn't need to be borrowed,
|
||||
// as in that case the call is more likely to return a
|
||||
// reference in the first place then.
|
||||
Call(..) | Path(..) => true,
|
||||
// If the `expr` is within a `Unary` or `BinOp` then
|
||||
// an assumption can be made that the operand is copy.
|
||||
// If not, then the value is moved and adding `.clone()`
|
||||
// will solve that issue. However, if the operand is
|
||||
// implicitly borrowed, then it's likely not even possible
|
||||
// to get the template to compile.
|
||||
_ => within_op && self.is_attr_self(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if this is an `Attr` where the `obj` is `"self"`.
|
||||
pub(crate) fn is_attr_self(&self) -> bool {
|
||||
match self {
|
||||
Expr::Attr(obj, _) if matches!(obj.as_ref(), Expr::Var("self")) => true,
|
||||
Expr::Attr(obj, _) if matches!(obj.as_ref(), Expr::Attr(..)) => obj.is_attr_self(),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the outcome of this expression may be used multiple times in the same
|
||||
/// `write!()` call, without evaluating the expression again, i.e. the expression should be
|
||||
/// side-effect free.
|
||||
pub(crate) fn is_cacheable(&self) -> bool {
|
||||
match self {
|
||||
// Literals are the definition of pure:
|
||||
Expr::BoolLit(_) => true,
|
||||
Expr::NumLit(_) => true,
|
||||
Expr::StrLit(_) => true,
|
||||
Expr::CharLit(_) => true,
|
||||
// fmt::Display should have no effects:
|
||||
Expr::Var(_) => true,
|
||||
Expr::Path(_) => true,
|
||||
// Check recursively:
|
||||
Expr::Array(args) => args.iter().all(|arg| arg.is_cacheable()),
|
||||
Expr::Attr(lhs, _) => lhs.is_cacheable(),
|
||||
Expr::Index(lhs, rhs) => lhs.is_cacheable() && rhs.is_cacheable(),
|
||||
Expr::Filter(_, args) => args.iter().all(|arg| arg.is_cacheable()),
|
||||
Expr::Unary(_, arg) => arg.is_cacheable(),
|
||||
Expr::BinOp(_, lhs, rhs) => lhs.is_cacheable() && rhs.is_cacheable(),
|
||||
Expr::Range(_, lhs, rhs) => {
|
||||
lhs.as_ref().map_or(true, |v| v.is_cacheable())
|
||||
&& rhs.as_ref().map_or(true, |v| v.is_cacheable())
|
||||
}
|
||||
Expr::Group(arg) => arg.is_cacheable(),
|
||||
Expr::Tuple(args) => args.iter().all(|arg| arg.is_cacheable()),
|
||||
// We have too little information to tell if the expression is pure:
|
||||
Expr::Call(_, _) => false,
|
||||
Expr::RustMacro(_, _) => false,
|
||||
Expr::Try(_) => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn expr_bool_lit(i: &str) -> IResult<&str, Expr<'_>> {
|
||||
map(bool_lit, Expr::BoolLit)(i)
|
||||
}
|
||||
|
||||
fn expr_num_lit(i: &str) -> IResult<&str, Expr<'_>> {
|
||||
map(num_lit, Expr::NumLit)(i)
|
||||
}
|
||||
|
||||
fn expr_array_lit(i: &str) -> IResult<&str, Expr<'_>> {
|
||||
delimited(
|
||||
ws(char('[')),
|
||||
map(separated_list1(ws(char(',')), expr_any), Expr::Array),
|
||||
ws(char(']')),
|
||||
)(i)
|
||||
}
|
||||
|
||||
fn expr_str_lit(i: &str) -> IResult<&str, Expr<'_>> {
|
||||
map(str_lit, Expr::StrLit)(i)
|
||||
}
|
||||
|
||||
fn expr_char_lit(i: &str) -> IResult<&str, Expr<'_>> {
|
||||
map(char_lit, Expr::CharLit)(i)
|
||||
}
|
||||
|
||||
fn expr_var(i: &str) -> IResult<&str, Expr<'_>> {
|
||||
map(identifier, Expr::Var)(i)
|
||||
}
|
||||
|
||||
fn expr_path(i: &str) -> IResult<&str, Expr<'_>> {
|
||||
let (i, path) = path(i)?;
|
||||
Ok((i, Expr::Path(path)))
|
||||
}
|
||||
|
||||
fn expr_group(i: &str) -> IResult<&str, Expr<'_>> {
|
||||
let (i, expr) = preceded(ws(char('(')), opt(expr_any))(i)?;
|
||||
let expr = match expr {
|
||||
Some(expr) => expr,
|
||||
None => {
|
||||
let (i, _) = char(')')(i)?;
|
||||
return Ok((i, Expr::Tuple(vec![])));
|
||||
}
|
||||
};
|
||||
|
||||
let (i, comma) = ws(opt(peek(char(','))))(i)?;
|
||||
if comma.is_none() {
|
||||
let (i, _) = char(')')(i)?;
|
||||
return Ok((i, Expr::Group(Box::new(expr))));
|
||||
}
|
||||
|
||||
let mut exprs = vec![expr];
|
||||
let (i, _) = fold_many0(
|
||||
preceded(char(','), ws(expr_any)),
|
||||
|| (),
|
||||
|_, expr| {
|
||||
exprs.push(expr);
|
||||
},
|
||||
)(i)?;
|
||||
let (i, _) = pair(ws(opt(char(','))), char(')'))(i)?;
|
||||
Ok((i, Expr::Tuple(exprs)))
|
||||
}
|
||||
|
||||
fn expr_single(i: &str) -> IResult<&str, Expr<'_>> {
|
||||
alt((
|
||||
expr_bool_lit,
|
||||
expr_num_lit,
|
||||
expr_str_lit,
|
||||
expr_char_lit,
|
||||
expr_path,
|
||||
expr_rust_macro,
|
||||
expr_array_lit,
|
||||
expr_var,
|
||||
expr_group,
|
||||
))(i)
|
||||
}
|
||||
|
||||
enum Suffix<'a> {
|
||||
Attr(&'a str),
|
||||
Index(Expr<'a>),
|
||||
Call(Vec<Expr<'a>>),
|
||||
Try,
|
||||
}
|
||||
|
||||
fn expr_attr(i: &str) -> IResult<&str, Suffix<'_>> {
|
||||
map(
|
||||
preceded(
|
||||
ws(pair(char('.'), not(char('.')))),
|
||||
cut(alt((num_lit, identifier))),
|
||||
),
|
||||
Suffix::Attr,
|
||||
)(i)
|
||||
}
|
||||
|
||||
fn expr_index(i: &str) -> IResult<&str, Suffix<'_>> {
|
||||
map(
|
||||
preceded(ws(char('[')), cut(terminated(expr_any, ws(char(']'))))),
|
||||
Suffix::Index,
|
||||
)(i)
|
||||
}
|
||||
|
||||
fn expr_call(i: &str) -> IResult<&str, Suffix<'_>> {
|
||||
map(arguments, Suffix::Call)(i)
|
||||
}
|
||||
|
||||
fn expr_try(i: &str) -> IResult<&str, Suffix<'_>> {
|
||||
map(preceded(take_till(not_ws), char('?')), |_| Suffix::Try)(i)
|
||||
}
|
||||
|
||||
fn filter(i: &str) -> IResult<&str, (&str, Option<Vec<Expr<'_>>>)> {
|
||||
let (i, (_, fname, args)) = tuple((char('|'), ws(identifier), opt(arguments)))(i)?;
|
||||
Ok((i, (fname, args)))
|
||||
}
|
||||
|
||||
fn expr_filtered(i: &str) -> IResult<&str, Expr<'_>> {
|
||||
let (i, (obj, filters)) = tuple((expr_prefix, many0(filter)))(i)?;
|
||||
|
||||
let mut res = obj;
|
||||
for (fname, args) in filters {
|
||||
res = Expr::Filter(fname, {
|
||||
let mut args = match args {
|
||||
Some(inner) => inner,
|
||||
None => Vec::new(),
|
||||
};
|
||||
args.insert(0, res);
|
||||
args
|
||||
});
|
||||
}
|
||||
|
||||
Ok((i, res))
|
||||
}
|
||||
|
||||
fn expr_prefix(i: &str) -> IResult<&str, Expr<'_>> {
|
||||
let (i, (ops, mut expr)) = pair(many0(ws(alt((tag("!"), tag("-"))))), expr_suffix)(i)?;
|
||||
for op in ops.iter().rev() {
|
||||
expr = Expr::Unary(op, Box::new(expr));
|
||||
}
|
||||
Ok((i, expr))
|
||||
}
|
||||
|
||||
fn expr_suffix(i: &str) -> IResult<&str, Expr<'_>> {
|
||||
let (mut i, mut expr) = expr_single(i)?;
|
||||
loop {
|
||||
let (j, suffix) = opt(alt((expr_attr, expr_index, expr_call, expr_try)))(i)?;
|
||||
i = j;
|
||||
match suffix {
|
||||
Some(Suffix::Attr(attr)) => expr = Expr::Attr(expr.into(), attr),
|
||||
Some(Suffix::Index(index)) => expr = Expr::Index(expr.into(), index.into()),
|
||||
Some(Suffix::Call(args)) => expr = Expr::Call(expr.into(), args),
|
||||
Some(Suffix::Try) => expr = Expr::Try(expr.into()),
|
||||
None => break,
|
||||
}
|
||||
}
|
||||
Ok((i, expr))
|
||||
}
|
||||
|
||||
fn macro_arguments(i: &str) -> IResult<&str, &str> {
|
||||
delimited(char('('), recognize(nested_parenthesis), char(')'))(i)
|
||||
}
|
||||
|
||||
fn expr_rust_macro(i: &str) -> IResult<&str, Expr<'_>> {
|
||||
let (i, (mname, _, args)) = tuple((identifier, char('!'), macro_arguments))(i)?;
|
||||
Ok((i, Expr::RustMacro(mname, args)))
|
||||
}
|
||||
|
||||
macro_rules! expr_prec_layer {
|
||||
( $name:ident, $inner:ident, $op:expr ) => {
|
||||
fn $name(i: &str) -> IResult<&str, Expr<'_>> {
|
||||
let (i, left) = $inner(i)?;
|
||||
let (i, right) = many0(pair(
|
||||
ws(tag($op)),
|
||||
$inner,
|
||||
))(i)?;
|
||||
Ok((
|
||||
i,
|
||||
right.into_iter().fold(left, |left, (op, right)| {
|
||||
Expr::BinOp(op, Box::new(left), Box::new(right))
|
||||
}),
|
||||
))
|
||||
}
|
||||
};
|
||||
( $name:ident, $inner:ident, $( $op:expr ),+ ) => {
|
||||
fn $name(i: &str) -> IResult<&str, Expr<'_>> {
|
||||
let (i, left) = $inner(i)?;
|
||||
let (i, right) = many0(pair(
|
||||
ws(alt(($( tag($op) ),+,))),
|
||||
$inner,
|
||||
))(i)?;
|
||||
Ok((
|
||||
i,
|
||||
right.into_iter().fold(left, |left, (op, right)| {
|
||||
Expr::BinOp(op, Box::new(left), Box::new(right))
|
||||
}),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
expr_prec_layer!(expr_muldivmod, expr_filtered, "*", "/", "%");
|
||||
expr_prec_layer!(expr_addsub, expr_muldivmod, "+", "-");
|
||||
expr_prec_layer!(expr_shifts, expr_addsub, ">>", "<<");
|
||||
expr_prec_layer!(expr_band, expr_shifts, "&");
|
||||
expr_prec_layer!(expr_bxor, expr_band, "^");
|
||||
expr_prec_layer!(expr_bor, expr_bxor, "|");
|
||||
expr_prec_layer!(expr_compare, expr_bor, "==", "!=", ">=", ">", "<=", "<");
|
||||
expr_prec_layer!(expr_and, expr_compare, "&&");
|
||||
expr_prec_layer!(expr_or, expr_and, "||");
|
||||
|
||||
fn expr_any(i: &str) -> IResult<&str, Expr<'_>> {
|
||||
let range_right = |i| pair(ws(alt((tag("..="), tag("..")))), opt(expr_or))(i);
|
||||
alt((
|
||||
map(range_right, |(op, right)| {
|
||||
Expr::Range(op, None, right.map(Box::new))
|
||||
}),
|
||||
map(
|
||||
pair(expr_or, opt(range_right)),
|
||||
|(left, right)| match right {
|
||||
Some((op, right)) => Expr::Range(op, Some(Box::new(left)), right.map(Box::new)),
|
||||
None => left,
|
||||
},
|
||||
),
|
||||
))(i)
|
||||
}
|
||||
|
||||
fn arguments(i: &str) -> IResult<&str, Vec<Expr<'_>>> {
|
||||
delimited(
|
||||
ws(char('(')),
|
||||
separated_list0(char(','), ws(expr_any)),
|
||||
ws(char(')')),
|
||||
)(i)
|
||||
}
|
||||
317
third_party/rust/askama_derive/src/parser/mod.rs
vendored
Normal file
317
third_party/rust/askama_derive/src/parser/mod.rs
vendored
Normal file
@@ -0,0 +1,317 @@
|
||||
use std::cell::Cell;
|
||||
use std::str;
|
||||
|
||||
use nom::branch::alt;
|
||||
use nom::bytes::complete::{escaped, is_not, tag, take_till};
|
||||
use nom::character::complete::char;
|
||||
use nom::character::complete::{anychar, digit1};
|
||||
use nom::combinator::{eof, map, not, opt, recognize, value};
|
||||
use nom::error::ErrorKind;
|
||||
use nom::multi::separated_list1;
|
||||
use nom::sequence::{delimited, pair, tuple};
|
||||
use nom::{error_position, AsChar, IResult, InputTakeAtPosition};
|
||||
|
||||
pub(crate) use self::expr::Expr;
|
||||
pub(crate) use self::node::{Cond, CondTest, Loop, Macro, Node, Target, When, Whitespace, Ws};
|
||||
use crate::config::Syntax;
|
||||
use crate::CompileError;
|
||||
|
||||
mod expr;
|
||||
mod node;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
struct State<'a> {
|
||||
syntax: &'a Syntax<'a>,
|
||||
loop_depth: Cell<usize>,
|
||||
}
|
||||
|
||||
impl<'a> State<'a> {
|
||||
fn new(syntax: &'a Syntax<'a>) -> State<'a> {
|
||||
State {
|
||||
syntax,
|
||||
loop_depth: Cell::new(0),
|
||||
}
|
||||
}
|
||||
|
||||
fn enter_loop(&self) {
|
||||
self.loop_depth.set(self.loop_depth.get() + 1);
|
||||
}
|
||||
|
||||
fn leave_loop(&self) {
|
||||
self.loop_depth.set(self.loop_depth.get() - 1);
|
||||
}
|
||||
|
||||
fn is_in_loop(&self) -> bool {
|
||||
self.loop_depth.get() > 0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<char> for Whitespace {
|
||||
fn from(c: char) -> Self {
|
||||
match c {
|
||||
'+' => Self::Preserve,
|
||||
'-' => Self::Suppress,
|
||||
'~' => Self::Minimize,
|
||||
_ => panic!("unsupported `Whitespace` conversion"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn parse<'a>(
|
||||
src: &'a str,
|
||||
syntax: &'a Syntax<'_>,
|
||||
) -> Result<Vec<Node<'a>>, CompileError> {
|
||||
match Node::parse(src, &State::new(syntax)) {
|
||||
Ok((left, res)) => {
|
||||
if !left.is_empty() {
|
||||
Err(format!("unable to parse template:\n\n{left:?}").into())
|
||||
} else {
|
||||
Ok(res)
|
||||
}
|
||||
}
|
||||
|
||||
Err(nom::Err::Error(err)) | Err(nom::Err::Failure(err)) => {
|
||||
let nom::error::Error { input, .. } = err;
|
||||
let offset = src.len() - input.len();
|
||||
let (source_before, source_after) = src.split_at(offset);
|
||||
|
||||
let source_after = match source_after.char_indices().enumerate().take(41).last() {
|
||||
Some((40, (i, _))) => format!("{:?}...", &source_after[..i]),
|
||||
_ => format!("{source_after:?}"),
|
||||
};
|
||||
|
||||
let (row, last_line) = source_before.lines().enumerate().last().unwrap();
|
||||
let column = last_line.chars().count();
|
||||
|
||||
let msg = format!(
|
||||
"problems parsing template source at row {}, column {} near:\n{}",
|
||||
row + 1,
|
||||
column,
|
||||
source_after,
|
||||
);
|
||||
Err(msg.into())
|
||||
}
|
||||
|
||||
Err(nom::Err::Incomplete(_)) => Err("parsing incomplete".into()),
|
||||
}
|
||||
}
|
||||
|
||||
fn is_ws(c: char) -> bool {
|
||||
matches!(c, ' ' | '\t' | '\r' | '\n')
|
||||
}
|
||||
|
||||
fn not_ws(c: char) -> bool {
|
||||
!is_ws(c)
|
||||
}
|
||||
|
||||
fn ws<'a, O>(
|
||||
inner: impl FnMut(&'a str) -> IResult<&'a str, O>,
|
||||
) -> impl FnMut(&'a str) -> IResult<&'a str, O> {
|
||||
delimited(take_till(not_ws), inner, take_till(not_ws))
|
||||
}
|
||||
|
||||
fn split_ws_parts(s: &str) -> Node<'_> {
|
||||
let trimmed_start = s.trim_start_matches(is_ws);
|
||||
let len_start = s.len() - trimmed_start.len();
|
||||
let trimmed = trimmed_start.trim_end_matches(is_ws);
|
||||
Node::Lit(&s[..len_start], trimmed, &trimmed_start[trimmed.len()..])
|
||||
}
|
||||
|
||||
/// Skips input until `end` was found, but does not consume it.
|
||||
/// Returns tuple that would be returned when parsing `end`.
|
||||
fn skip_till<'a, O>(
|
||||
end: impl FnMut(&'a str) -> IResult<&'a str, O>,
|
||||
) -> impl FnMut(&'a str) -> IResult<&'a str, (&'a str, O)> {
|
||||
enum Next<O> {
|
||||
IsEnd(O),
|
||||
NotEnd(char),
|
||||
}
|
||||
let mut next = alt((map(end, Next::IsEnd), map(anychar, Next::NotEnd)));
|
||||
move |start: &'a str| {
|
||||
let mut i = start;
|
||||
loop {
|
||||
let (j, is_end) = next(i)?;
|
||||
match is_end {
|
||||
Next::IsEnd(lookahead) => return Ok((i, (j, lookahead))),
|
||||
Next::NotEnd(_) => i = j,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn keyword<'a>(k: &'a str) -> impl FnMut(&'a str) -> IResult<&'a str, &'a str> {
|
||||
move |i: &'a str| -> IResult<&'a str, &'a str> {
|
||||
let (j, v) = identifier(i)?;
|
||||
if k == v {
|
||||
Ok((j, v))
|
||||
} else {
|
||||
Err(nom::Err::Error(error_position!(i, ErrorKind::Tag)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn identifier(input: &str) -> IResult<&str, &str> {
|
||||
recognize(pair(identifier_start, opt(identifier_tail)))(input)
|
||||
}
|
||||
|
||||
fn identifier_start(s: &str) -> IResult<&str, &str> {
|
||||
s.split_at_position1_complete(
|
||||
|c| !(c.is_alpha() || c == '_' || c >= '\u{0080}'),
|
||||
nom::error::ErrorKind::Alpha,
|
||||
)
|
||||
}
|
||||
|
||||
fn identifier_tail(s: &str) -> IResult<&str, &str> {
|
||||
s.split_at_position1_complete(
|
||||
|c| !(c.is_alphanum() || c == '_' || c >= '\u{0080}'),
|
||||
nom::error::ErrorKind::Alpha,
|
||||
)
|
||||
}
|
||||
|
||||
fn bool_lit(i: &str) -> IResult<&str, &str> {
|
||||
alt((keyword("false"), keyword("true")))(i)
|
||||
}
|
||||
|
||||
fn num_lit(i: &str) -> IResult<&str, &str> {
|
||||
recognize(pair(digit1, opt(pair(char('.'), digit1))))(i)
|
||||
}
|
||||
|
||||
fn str_lit(i: &str) -> IResult<&str, &str> {
|
||||
let (i, s) = delimited(
|
||||
char('"'),
|
||||
opt(escaped(is_not("\\\""), '\\', anychar)),
|
||||
char('"'),
|
||||
)(i)?;
|
||||
Ok((i, s.unwrap_or_default()))
|
||||
}
|
||||
|
||||
fn char_lit(i: &str) -> IResult<&str, &str> {
|
||||
let (i, s) = delimited(
|
||||
char('\''),
|
||||
opt(escaped(is_not("\\\'"), '\\', anychar)),
|
||||
char('\''),
|
||||
)(i)?;
|
||||
Ok((i, s.unwrap_or_default()))
|
||||
}
|
||||
|
||||
fn nested_parenthesis(i: &str) -> IResult<&str, ()> {
|
||||
let mut nested = 0;
|
||||
let mut last = 0;
|
||||
let mut in_str = false;
|
||||
let mut escaped = false;
|
||||
|
||||
for (i, b) in i.chars().enumerate() {
|
||||
if !(b == '(' || b == ')') || !in_str {
|
||||
match b {
|
||||
'(' => nested += 1,
|
||||
')' => {
|
||||
if nested == 0 {
|
||||
last = i;
|
||||
break;
|
||||
}
|
||||
nested -= 1;
|
||||
}
|
||||
'"' => {
|
||||
if in_str {
|
||||
if !escaped {
|
||||
in_str = false;
|
||||
}
|
||||
} else {
|
||||
in_str = true;
|
||||
}
|
||||
}
|
||||
'\\' => {
|
||||
escaped = !escaped;
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
if escaped && b != '\\' {
|
||||
escaped = false;
|
||||
}
|
||||
}
|
||||
|
||||
if nested == 0 {
|
||||
Ok((&i[last..], ()))
|
||||
} else {
|
||||
Err(nom::Err::Error(error_position!(
|
||||
i,
|
||||
ErrorKind::SeparatedNonEmptyList
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
fn path(i: &str) -> IResult<&str, Vec<&str>> {
|
||||
let root = opt(value("", ws(tag("::"))));
|
||||
let tail = separated_list1(ws(tag("::")), identifier);
|
||||
|
||||
match tuple((root, identifier, ws(tag("::")), tail))(i) {
|
||||
Ok((i, (root, start, _, rest))) => {
|
||||
let mut path = Vec::new();
|
||||
path.extend(root);
|
||||
path.push(start);
|
||||
path.extend(rest);
|
||||
Ok((i, path))
|
||||
}
|
||||
Err(err) => {
|
||||
if let Ok((i, name)) = identifier(i) {
|
||||
// The returned identifier can be assumed to be path if:
|
||||
// - Contains both a lowercase and uppercase character, i.e. a type name like `None`
|
||||
// - Doesn't contain any lowercase characters, i.e. it's a constant
|
||||
// In short, if it contains any uppercase characters it's a path.
|
||||
if name.contains(char::is_uppercase) {
|
||||
return Ok((i, vec![name]));
|
||||
}
|
||||
}
|
||||
|
||||
// If `identifier()` fails then just return the original error
|
||||
Err(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn take_content<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, Node<'a>> {
|
||||
let p_start = alt((
|
||||
tag(s.syntax.block_start),
|
||||
tag(s.syntax.comment_start),
|
||||
tag(s.syntax.expr_start),
|
||||
));
|
||||
|
||||
let (i, _) = not(eof)(i)?;
|
||||
let (i, content) = opt(recognize(skip_till(p_start)))(i)?;
|
||||
let (i, content) = match content {
|
||||
Some("") => {
|
||||
// {block,comment,expr}_start follows immediately.
|
||||
return Err(nom::Err::Error(error_position!(i, ErrorKind::TakeUntil)));
|
||||
}
|
||||
Some(content) => (i, content),
|
||||
None => ("", i), // there is no {block,comment,expr}_start: take everything
|
||||
};
|
||||
Ok((i, split_ws_parts(content)))
|
||||
}
|
||||
|
||||
fn tag_block_start<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, &'a str> {
|
||||
tag(s.syntax.block_start)(i)
|
||||
}
|
||||
|
||||
fn tag_block_end<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, &'a str> {
|
||||
tag(s.syntax.block_end)(i)
|
||||
}
|
||||
|
||||
fn tag_comment_start<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, &'a str> {
|
||||
tag(s.syntax.comment_start)(i)
|
||||
}
|
||||
|
||||
fn tag_comment_end<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, &'a str> {
|
||||
tag(s.syntax.comment_end)(i)
|
||||
}
|
||||
|
||||
fn tag_expr_start<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, &'a str> {
|
||||
tag(s.syntax.expr_start)(i)
|
||||
}
|
||||
|
||||
fn tag_expr_end<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, &'a str> {
|
||||
tag(s.syntax.expr_end)(i)
|
||||
}
|
||||
682
third_party/rust/askama_derive/src/parser/node.rs
vendored
Normal file
682
third_party/rust/askama_derive/src/parser/node.rs
vendored
Normal file
@@ -0,0 +1,682 @@
|
||||
use std::str;
|
||||
|
||||
use nom::branch::alt;
|
||||
use nom::bytes::complete::{tag, take_until};
|
||||
use nom::character::complete::char;
|
||||
use nom::combinator::{complete, consumed, cut, map, opt, peek, value};
|
||||
use nom::error::{Error, ErrorKind};
|
||||
use nom::multi::{fold_many0, many0, many1, separated_list0, separated_list1};
|
||||
use nom::sequence::{delimited, pair, preceded, terminated, tuple};
|
||||
use nom::{error_position, IResult};
|
||||
|
||||
use super::{
|
||||
bool_lit, char_lit, identifier, keyword, num_lit, path, skip_till, split_ws_parts, str_lit,
|
||||
tag_block_end, tag_block_start, tag_comment_end, tag_comment_start, tag_expr_end,
|
||||
tag_expr_start, take_content, ws, Expr, State,
|
||||
};
|
||||
use crate::config::WhitespaceHandling;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub(crate) enum Node<'a> {
|
||||
Lit(&'a str, &'a str, &'a str),
|
||||
Comment(Ws),
|
||||
Expr(Ws, Expr<'a>),
|
||||
Call(Ws, Option<&'a str>, &'a str, Vec<Expr<'a>>),
|
||||
LetDecl(Ws, Target<'a>),
|
||||
Let(Ws, Target<'a>, Expr<'a>),
|
||||
Cond(Vec<Cond<'a>>, Ws),
|
||||
Match(Ws, Expr<'a>, Vec<When<'a>>, Ws),
|
||||
Loop(Loop<'a>),
|
||||
Extends(&'a str),
|
||||
BlockDef(Ws, &'a str, Vec<Node<'a>>, Ws),
|
||||
Include(Ws, &'a str),
|
||||
Import(Ws, &'a str, &'a str),
|
||||
Macro(&'a str, Macro<'a>),
|
||||
Raw(Ws, &'a str, &'a str, &'a str, Ws),
|
||||
Break(Ws),
|
||||
Continue(Ws),
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub(crate) enum Target<'a> {
|
||||
Name(&'a str),
|
||||
Tuple(Vec<&'a str>, Vec<Target<'a>>),
|
||||
Struct(Vec<&'a str>, Vec<(&'a str, Target<'a>)>),
|
||||
NumLit(&'a str),
|
||||
StrLit(&'a str),
|
||||
CharLit(&'a str),
|
||||
BoolLit(&'a str),
|
||||
Path(Vec<&'a str>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub(crate) enum Whitespace {
|
||||
Preserve,
|
||||
Suppress,
|
||||
Minimize,
|
||||
}
|
||||
|
||||
impl From<WhitespaceHandling> for Whitespace {
|
||||
fn from(ws: WhitespaceHandling) -> Self {
|
||||
match ws {
|
||||
WhitespaceHandling::Suppress => Whitespace::Suppress,
|
||||
WhitespaceHandling::Preserve => Whitespace::Preserve,
|
||||
WhitespaceHandling::Minimize => Whitespace::Minimize,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub(crate) struct Loop<'a> {
|
||||
pub(crate) ws1: Ws,
|
||||
pub(crate) var: Target<'a>,
|
||||
pub(crate) iter: Expr<'a>,
|
||||
pub(crate) cond: Option<Expr<'a>>,
|
||||
pub(crate) body: Vec<Node<'a>>,
|
||||
pub(crate) ws2: Ws,
|
||||
pub(crate) else_block: Vec<Node<'a>>,
|
||||
pub(crate) ws3: Ws,
|
||||
}
|
||||
|
||||
pub(crate) type When<'a> = (Ws, Target<'a>, Vec<Node<'a>>);
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub(crate) struct Macro<'a> {
|
||||
pub(crate) ws1: Ws,
|
||||
pub(crate) args: Vec<&'a str>,
|
||||
pub(crate) nodes: Vec<Node<'a>>,
|
||||
pub(crate) ws2: Ws,
|
||||
}
|
||||
|
||||
/// First field is "minus/plus sign was used on the left part of the item".
|
||||
///
|
||||
/// Second field is "minus/plus sign was used on the right part of the item".
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub(crate) struct Ws(pub(crate) Option<Whitespace>, pub(crate) Option<Whitespace>);
|
||||
|
||||
pub(crate) type Cond<'a> = (Ws, Option<CondTest<'a>>, Vec<Node<'a>>);
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub(crate) struct CondTest<'a> {
|
||||
pub(crate) target: Option<Target<'a>>,
|
||||
pub(crate) expr: Expr<'a>,
|
||||
}
|
||||
|
||||
impl Node<'_> {
|
||||
pub(super) fn parse<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, Vec<Node<'a>>> {
|
||||
parse_template(i, s)
|
||||
}
|
||||
}
|
||||
|
||||
impl Target<'_> {
|
||||
pub(super) fn parse(i: &str) -> IResult<&str, Target<'_>> {
|
||||
target(i)
|
||||
}
|
||||
}
|
||||
|
||||
fn expr_handle_ws(i: &str) -> IResult<&str, Whitespace> {
|
||||
alt((char('-'), char('+'), char('~')))(i).map(|(s, r)| (s, Whitespace::from(r)))
|
||||
}
|
||||
|
||||
fn parameters(i: &str) -> IResult<&str, Vec<&str>> {
|
||||
delimited(
|
||||
ws(char('(')),
|
||||
separated_list0(char(','), ws(identifier)),
|
||||
ws(char(')')),
|
||||
)(i)
|
||||
}
|
||||
|
||||
fn block_call(i: &str) -> IResult<&str, Node<'_>> {
|
||||
let mut p = tuple((
|
||||
opt(expr_handle_ws),
|
||||
ws(keyword("call")),
|
||||
cut(tuple((
|
||||
opt(tuple((ws(identifier), ws(tag("::"))))),
|
||||
ws(identifier),
|
||||
ws(Expr::parse_arguments),
|
||||
opt(expr_handle_ws),
|
||||
))),
|
||||
));
|
||||
let (i, (pws, _, (scope, name, args, nws))) = p(i)?;
|
||||
let scope = scope.map(|(scope, _)| scope);
|
||||
Ok((i, Node::Call(Ws(pws, nws), scope, name, args)))
|
||||
}
|
||||
|
||||
fn cond_if(i: &str) -> IResult<&str, CondTest<'_>> {
|
||||
let mut p = preceded(
|
||||
ws(keyword("if")),
|
||||
cut(tuple((
|
||||
opt(delimited(
|
||||
ws(alt((keyword("let"), keyword("set")))),
|
||||
ws(Target::parse),
|
||||
ws(char('=')),
|
||||
)),
|
||||
ws(Expr::parse),
|
||||
))),
|
||||
);
|
||||
let (i, (target, expr)) = p(i)?;
|
||||
Ok((i, CondTest { target, expr }))
|
||||
}
|
||||
|
||||
fn cond_block<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, Cond<'a>> {
|
||||
let mut p = tuple((
|
||||
|i| tag_block_start(i, s),
|
||||
opt(expr_handle_ws),
|
||||
ws(keyword("else")),
|
||||
cut(tuple((
|
||||
opt(cond_if),
|
||||
opt(expr_handle_ws),
|
||||
|i| tag_block_end(i, s),
|
||||
cut(|i| parse_template(i, s)),
|
||||
))),
|
||||
));
|
||||
let (i, (_, pws, _, (cond, nws, _, block))) = p(i)?;
|
||||
Ok((i, (Ws(pws, nws), cond, block)))
|
||||
}
|
||||
|
||||
fn block_if<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, Node<'a>> {
|
||||
let mut p = tuple((
|
||||
opt(expr_handle_ws),
|
||||
cond_if,
|
||||
cut(tuple((
|
||||
opt(expr_handle_ws),
|
||||
|i| tag_block_end(i, s),
|
||||
cut(tuple((
|
||||
|i| parse_template(i, s),
|
||||
many0(|i| cond_block(i, s)),
|
||||
cut(tuple((
|
||||
|i| tag_block_start(i, s),
|
||||
opt(expr_handle_ws),
|
||||
ws(keyword("endif")),
|
||||
opt(expr_handle_ws),
|
||||
))),
|
||||
))),
|
||||
))),
|
||||
));
|
||||
let (i, (pws1, cond, (nws1, _, (block, elifs, (_, pws2, _, nws2))))) = p(i)?;
|
||||
|
||||
let mut res = vec![(Ws(pws1, nws1), Some(cond), block)];
|
||||
res.extend(elifs);
|
||||
Ok((i, Node::Cond(res, Ws(pws2, nws2))))
|
||||
}
|
||||
|
||||
fn match_else_block<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, When<'a>> {
|
||||
let mut p = tuple((
|
||||
|i| tag_block_start(i, s),
|
||||
opt(expr_handle_ws),
|
||||
ws(keyword("else")),
|
||||
cut(tuple((
|
||||
opt(expr_handle_ws),
|
||||
|i| tag_block_end(i, s),
|
||||
cut(|i| parse_template(i, s)),
|
||||
))),
|
||||
));
|
||||
let (i, (_, pws, _, (nws, _, block))) = p(i)?;
|
||||
Ok((i, (Ws(pws, nws), Target::Name("_"), block)))
|
||||
}
|
||||
|
||||
fn when_block<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, When<'a>> {
|
||||
let mut p = tuple((
|
||||
|i| tag_block_start(i, s),
|
||||
opt(expr_handle_ws),
|
||||
ws(keyword("when")),
|
||||
cut(tuple((
|
||||
ws(Target::parse),
|
||||
opt(expr_handle_ws),
|
||||
|i| tag_block_end(i, s),
|
||||
cut(|i| parse_template(i, s)),
|
||||
))),
|
||||
));
|
||||
let (i, (_, pws, _, (target, nws, _, block))) = p(i)?;
|
||||
Ok((i, (Ws(pws, nws), target, block)))
|
||||
}
|
||||
|
||||
fn block_match<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, Node<'a>> {
|
||||
let mut p = tuple((
|
||||
opt(expr_handle_ws),
|
||||
ws(keyword("match")),
|
||||
cut(tuple((
|
||||
ws(Expr::parse),
|
||||
opt(expr_handle_ws),
|
||||
|i| tag_block_end(i, s),
|
||||
cut(tuple((
|
||||
ws(many0(ws(value((), |i| block_comment(i, s))))),
|
||||
many1(|i| when_block(i, s)),
|
||||
cut(tuple((
|
||||
opt(|i| match_else_block(i, s)),
|
||||
cut(tuple((
|
||||
ws(|i| tag_block_start(i, s)),
|
||||
opt(expr_handle_ws),
|
||||
ws(keyword("endmatch")),
|
||||
opt(expr_handle_ws),
|
||||
))),
|
||||
))),
|
||||
))),
|
||||
))),
|
||||
));
|
||||
let (i, (pws1, _, (expr, nws1, _, (_, arms, (else_arm, (_, pws2, _, nws2)))))) = p(i)?;
|
||||
|
||||
let mut arms = arms;
|
||||
if let Some(arm) = else_arm {
|
||||
arms.push(arm);
|
||||
}
|
||||
|
||||
Ok((i, Node::Match(Ws(pws1, nws1), expr, arms, Ws(pws2, nws2))))
|
||||
}
|
||||
|
||||
fn block_let(i: &str) -> IResult<&str, Node<'_>> {
|
||||
let mut p = tuple((
|
||||
opt(expr_handle_ws),
|
||||
ws(alt((keyword("let"), keyword("set")))),
|
||||
cut(tuple((
|
||||
ws(Target::parse),
|
||||
opt(tuple((ws(char('=')), ws(Expr::parse)))),
|
||||
opt(expr_handle_ws),
|
||||
))),
|
||||
));
|
||||
let (i, (pws, _, (var, val, nws))) = p(i)?;
|
||||
|
||||
Ok((
|
||||
i,
|
||||
if let Some((_, val)) = val {
|
||||
Node::Let(Ws(pws, nws), var, val)
|
||||
} else {
|
||||
Node::LetDecl(Ws(pws, nws), var)
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
fn parse_loop_content<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, Vec<Node<'a>>> {
|
||||
s.enter_loop();
|
||||
let result = parse_template(i, s);
|
||||
s.leave_loop();
|
||||
result
|
||||
}
|
||||
|
||||
fn block_for<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, Node<'a>> {
|
||||
let if_cond = preceded(ws(keyword("if")), cut(ws(Expr::parse)));
|
||||
let else_block = |i| {
|
||||
let mut p = preceded(
|
||||
ws(keyword("else")),
|
||||
cut(tuple((
|
||||
opt(expr_handle_ws),
|
||||
delimited(
|
||||
|i| tag_block_end(i, s),
|
||||
|i| parse_template(i, s),
|
||||
|i| tag_block_start(i, s),
|
||||
),
|
||||
opt(expr_handle_ws),
|
||||
))),
|
||||
);
|
||||
let (i, (pws, nodes, nws)) = p(i)?;
|
||||
Ok((i, (pws, nodes, nws)))
|
||||
};
|
||||
let mut p = tuple((
|
||||
opt(expr_handle_ws),
|
||||
ws(keyword("for")),
|
||||
cut(tuple((
|
||||
ws(Target::parse),
|
||||
ws(keyword("in")),
|
||||
cut(tuple((
|
||||
ws(Expr::parse),
|
||||
opt(if_cond),
|
||||
opt(expr_handle_ws),
|
||||
|i| tag_block_end(i, s),
|
||||
cut(tuple((
|
||||
|i| parse_loop_content(i, s),
|
||||
cut(tuple((
|
||||
|i| tag_block_start(i, s),
|
||||
opt(expr_handle_ws),
|
||||
opt(else_block),
|
||||
ws(keyword("endfor")),
|
||||
opt(expr_handle_ws),
|
||||
))),
|
||||
))),
|
||||
))),
|
||||
))),
|
||||
));
|
||||
let (i, (pws1, _, (var, _, (iter, cond, nws1, _, (body, (_, pws2, else_block, _, nws2)))))) =
|
||||
p(i)?;
|
||||
let (nws3, else_block, pws3) = else_block.unwrap_or_default();
|
||||
Ok((
|
||||
i,
|
||||
Node::Loop(Loop {
|
||||
ws1: Ws(pws1, nws1),
|
||||
var,
|
||||
iter,
|
||||
cond,
|
||||
body,
|
||||
ws2: Ws(pws2, nws3),
|
||||
else_block,
|
||||
ws3: Ws(pws3, nws2),
|
||||
}),
|
||||
))
|
||||
}
|
||||
|
||||
fn block_extends(i: &str) -> IResult<&str, Node<'_>> {
|
||||
let (i, (_, name)) = tuple((ws(keyword("extends")), ws(str_lit)))(i)?;
|
||||
Ok((i, Node::Extends(name)))
|
||||
}
|
||||
|
||||
fn block_block<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, Node<'a>> {
|
||||
let mut start = tuple((
|
||||
opt(expr_handle_ws),
|
||||
ws(keyword("block")),
|
||||
cut(tuple((ws(identifier), opt(expr_handle_ws), |i| {
|
||||
tag_block_end(i, s)
|
||||
}))),
|
||||
));
|
||||
let (i, (pws1, _, (name, nws1, _))) = start(i)?;
|
||||
|
||||
let mut end = cut(tuple((
|
||||
|i| parse_template(i, s),
|
||||
cut(tuple((
|
||||
|i| tag_block_start(i, s),
|
||||
opt(expr_handle_ws),
|
||||
ws(keyword("endblock")),
|
||||
cut(tuple((opt(ws(keyword(name))), opt(expr_handle_ws)))),
|
||||
))),
|
||||
)));
|
||||
let (i, (contents, (_, pws2, _, (_, nws2)))) = end(i)?;
|
||||
|
||||
Ok((
|
||||
i,
|
||||
Node::BlockDef(Ws(pws1, nws1), name, contents, Ws(pws2, nws2)),
|
||||
))
|
||||
}
|
||||
|
||||
fn block_include(i: &str) -> IResult<&str, Node<'_>> {
|
||||
let mut p = tuple((
|
||||
opt(expr_handle_ws),
|
||||
ws(keyword("include")),
|
||||
cut(pair(ws(str_lit), opt(expr_handle_ws))),
|
||||
));
|
||||
let (i, (pws, _, (name, nws))) = p(i)?;
|
||||
Ok((i, Node::Include(Ws(pws, nws), name)))
|
||||
}
|
||||
|
||||
fn block_import(i: &str) -> IResult<&str, Node<'_>> {
|
||||
let mut p = tuple((
|
||||
opt(expr_handle_ws),
|
||||
ws(keyword("import")),
|
||||
cut(tuple((
|
||||
ws(str_lit),
|
||||
ws(keyword("as")),
|
||||
cut(pair(ws(identifier), opt(expr_handle_ws))),
|
||||
))),
|
||||
));
|
||||
let (i, (pws, _, (name, _, (scope, nws)))) = p(i)?;
|
||||
Ok((i, Node::Import(Ws(pws, nws), name, scope)))
|
||||
}
|
||||
|
||||
fn block_macro<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, Node<'a>> {
|
||||
let mut start = tuple((
|
||||
opt(expr_handle_ws),
|
||||
ws(keyword("macro")),
|
||||
cut(tuple((
|
||||
ws(identifier),
|
||||
ws(parameters),
|
||||
opt(expr_handle_ws),
|
||||
|i| tag_block_end(i, s),
|
||||
))),
|
||||
));
|
||||
let (i, (pws1, _, (name, params, nws1, _))) = start(i)?;
|
||||
|
||||
let mut end = cut(tuple((
|
||||
|i| parse_template(i, s),
|
||||
cut(tuple((
|
||||
|i| tag_block_start(i, s),
|
||||
opt(expr_handle_ws),
|
||||
ws(keyword("endmacro")),
|
||||
cut(tuple((opt(ws(keyword(name))), opt(expr_handle_ws)))),
|
||||
))),
|
||||
)));
|
||||
let (i, (contents, (_, pws2, _, (_, nws2)))) = end(i)?;
|
||||
|
||||
assert_ne!(name, "super", "invalid macro name 'super'");
|
||||
|
||||
Ok((
|
||||
i,
|
||||
Node::Macro(
|
||||
name,
|
||||
Macro {
|
||||
ws1: Ws(pws1, nws1),
|
||||
args: params,
|
||||
nodes: contents,
|
||||
ws2: Ws(pws2, nws2),
|
||||
},
|
||||
),
|
||||
))
|
||||
}
|
||||
|
||||
fn block_raw<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, Node<'a>> {
|
||||
let endraw = tuple((
|
||||
|i| tag_block_start(i, s),
|
||||
opt(expr_handle_ws),
|
||||
ws(keyword("endraw")),
|
||||
opt(expr_handle_ws),
|
||||
peek(|i| tag_block_end(i, s)),
|
||||
));
|
||||
|
||||
let mut p = tuple((
|
||||
opt(expr_handle_ws),
|
||||
ws(keyword("raw")),
|
||||
cut(tuple((
|
||||
opt(expr_handle_ws),
|
||||
|i| tag_block_end(i, s),
|
||||
consumed(skip_till(endraw)),
|
||||
))),
|
||||
));
|
||||
|
||||
let (_, (pws1, _, (nws1, _, (contents, (i, (_, pws2, _, nws2, _)))))) = p(i)?;
|
||||
let (lws, val, rws) = match split_ws_parts(contents) {
|
||||
Node::Lit(lws, val, rws) => (lws, val, rws),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let ws1 = Ws(pws1, nws1);
|
||||
let ws2 = Ws(pws2, nws2);
|
||||
Ok((i, Node::Raw(ws1, lws, val, rws, ws2)))
|
||||
}
|
||||
|
||||
fn break_statement<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, Node<'a>> {
|
||||
let mut p = tuple((
|
||||
opt(expr_handle_ws),
|
||||
ws(keyword("break")),
|
||||
opt(expr_handle_ws),
|
||||
));
|
||||
let (j, (pws, _, nws)) = p(i)?;
|
||||
if !s.is_in_loop() {
|
||||
return Err(nom::Err::Failure(error_position!(i, ErrorKind::Tag)));
|
||||
}
|
||||
Ok((j, Node::Break(Ws(pws, nws))))
|
||||
}
|
||||
|
||||
fn continue_statement<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, Node<'a>> {
|
||||
let mut p = tuple((
|
||||
opt(expr_handle_ws),
|
||||
ws(keyword("continue")),
|
||||
opt(expr_handle_ws),
|
||||
));
|
||||
let (j, (pws, _, nws)) = p(i)?;
|
||||
if !s.is_in_loop() {
|
||||
return Err(nom::Err::Failure(error_position!(i, ErrorKind::Tag)));
|
||||
}
|
||||
Ok((j, Node::Continue(Ws(pws, nws))))
|
||||
}
|
||||
|
||||
fn block_node<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, Node<'a>> {
|
||||
let mut p = tuple((
|
||||
|i| tag_block_start(i, s),
|
||||
alt((
|
||||
block_call,
|
||||
block_let,
|
||||
|i| block_if(i, s),
|
||||
|i| block_for(i, s),
|
||||
|i| block_match(i, s),
|
||||
block_extends,
|
||||
block_include,
|
||||
block_import,
|
||||
|i| block_block(i, s),
|
||||
|i| block_macro(i, s),
|
||||
|i| block_raw(i, s),
|
||||
|i| break_statement(i, s),
|
||||
|i| continue_statement(i, s),
|
||||
)),
|
||||
cut(|i| tag_block_end(i, s)),
|
||||
));
|
||||
let (i, (_, contents, _)) = p(i)?;
|
||||
Ok((i, contents))
|
||||
}
|
||||
|
||||
fn block_comment_body<'a>(mut i: &'a str, s: &State<'_>) -> IResult<&'a str, &'a str> {
|
||||
let mut level = 0;
|
||||
loop {
|
||||
let (end, tail) = take_until(s.syntax.comment_end)(i)?;
|
||||
match take_until::<_, _, Error<_>>(s.syntax.comment_start)(i) {
|
||||
Ok((start, _)) if start.as_ptr() < end.as_ptr() => {
|
||||
level += 1;
|
||||
i = &start[2..];
|
||||
}
|
||||
_ if level > 0 => {
|
||||
level -= 1;
|
||||
i = &end[2..];
|
||||
}
|
||||
_ => return Ok((end, tail)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn block_comment<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, Node<'a>> {
|
||||
let mut p = tuple((
|
||||
|i| tag_comment_start(i, s),
|
||||
cut(tuple((
|
||||
opt(expr_handle_ws),
|
||||
|i| block_comment_body(i, s),
|
||||
|i| tag_comment_end(i, s),
|
||||
))),
|
||||
));
|
||||
let (i, (_, (pws, tail, _))) = p(i)?;
|
||||
let nws = if tail.ends_with('-') {
|
||||
Some(Whitespace::Suppress)
|
||||
} else if tail.ends_with('+') {
|
||||
Some(Whitespace::Preserve)
|
||||
} else if tail.ends_with('~') {
|
||||
Some(Whitespace::Minimize)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
Ok((i, Node::Comment(Ws(pws, nws))))
|
||||
}
|
||||
|
||||
fn expr_node<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, Node<'a>> {
|
||||
let mut p = tuple((
|
||||
|i| tag_expr_start(i, s),
|
||||
cut(tuple((
|
||||
opt(expr_handle_ws),
|
||||
ws(Expr::parse),
|
||||
opt(expr_handle_ws),
|
||||
|i| tag_expr_end(i, s),
|
||||
))),
|
||||
));
|
||||
let (i, (_, (pws, expr, nws, _))) = p(i)?;
|
||||
Ok((i, Node::Expr(Ws(pws, nws), expr)))
|
||||
}
|
||||
|
||||
fn parse_template<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, Vec<Node<'a>>> {
|
||||
many0(alt((
|
||||
complete(|i| take_content(i, s)),
|
||||
complete(|i| block_comment(i, s)),
|
||||
complete(|i| expr_node(i, s)),
|
||||
complete(|i| block_node(i, s)),
|
||||
)))(i)
|
||||
}
|
||||
|
||||
fn variant_lit(i: &str) -> IResult<&str, Target<'_>> {
|
||||
alt((
|
||||
map(str_lit, Target::StrLit),
|
||||
map(char_lit, Target::CharLit),
|
||||
map(num_lit, Target::NumLit),
|
||||
map(bool_lit, Target::BoolLit),
|
||||
))(i)
|
||||
}
|
||||
|
||||
fn target(i: &str) -> IResult<&str, Target<'_>> {
|
||||
let mut opt_opening_paren = map(opt(ws(char('('))), |o| o.is_some());
|
||||
let mut opt_closing_paren = map(opt(ws(char(')'))), |o| o.is_some());
|
||||
let mut opt_opening_brace = map(opt(ws(char('{'))), |o| o.is_some());
|
||||
|
||||
let (i, lit) = opt(variant_lit)(i)?;
|
||||
if let Some(lit) = lit {
|
||||
return Ok((i, lit));
|
||||
}
|
||||
|
||||
// match tuples and unused parentheses
|
||||
let (i, target_is_tuple) = opt_opening_paren(i)?;
|
||||
if target_is_tuple {
|
||||
let (i, is_empty_tuple) = opt_closing_paren(i)?;
|
||||
if is_empty_tuple {
|
||||
return Ok((i, Target::Tuple(Vec::new(), Vec::new())));
|
||||
}
|
||||
|
||||
let (i, first_target) = target(i)?;
|
||||
let (i, is_unused_paren) = opt_closing_paren(i)?;
|
||||
if is_unused_paren {
|
||||
return Ok((i, first_target));
|
||||
}
|
||||
|
||||
let mut targets = vec![first_target];
|
||||
let (i, _) = cut(tuple((
|
||||
fold_many0(
|
||||
preceded(ws(char(',')), target),
|
||||
|| (),
|
||||
|_, target| {
|
||||
targets.push(target);
|
||||
},
|
||||
),
|
||||
opt(ws(char(','))),
|
||||
ws(cut(char(')'))),
|
||||
)))(i)?;
|
||||
return Ok((i, Target::Tuple(Vec::new(), targets)));
|
||||
}
|
||||
|
||||
// match structs
|
||||
let (i, path) = opt(path)(i)?;
|
||||
if let Some(path) = path {
|
||||
let i_before_matching_with = i;
|
||||
let (i, _) = opt(ws(keyword("with")))(i)?;
|
||||
|
||||
let (i, is_unnamed_struct) = opt_opening_paren(i)?;
|
||||
if is_unnamed_struct {
|
||||
let (i, targets) = alt((
|
||||
map(char(')'), |_| Vec::new()),
|
||||
terminated(
|
||||
cut(separated_list1(ws(char(',')), target)),
|
||||
pair(opt(ws(char(','))), ws(cut(char(')')))),
|
||||
),
|
||||
))(i)?;
|
||||
return Ok((i, Target::Tuple(path, targets)));
|
||||
}
|
||||
|
||||
let (i, is_named_struct) = opt_opening_brace(i)?;
|
||||
if is_named_struct {
|
||||
let (i, targets) = alt((
|
||||
map(char('}'), |_| Vec::new()),
|
||||
terminated(
|
||||
cut(separated_list1(ws(char(',')), named_target)),
|
||||
pair(opt(ws(char(','))), ws(cut(char('}')))),
|
||||
),
|
||||
))(i)?;
|
||||
return Ok((i, Target::Struct(path, targets)));
|
||||
}
|
||||
|
||||
return Ok((i_before_matching_with, Target::Path(path)));
|
||||
}
|
||||
|
||||
// neither literal nor struct nor path
|
||||
map(identifier, Target::Name)(i)
|
||||
}
|
||||
|
||||
fn named_target(i: &str) -> IResult<&str, (&str, Target<'_>)> {
|
||||
let (i, (src, target)) = pair(identifier, opt(preceded(ws(char(':')), target)))(i)?;
|
||||
Ok((i, (src, target.unwrap_or(Target::Name(src)))))
|
||||
}
|
||||
668
third_party/rust/askama_derive/src/parser/tests.rs
vendored
Normal file
668
third_party/rust/askama_derive/src/parser/tests.rs
vendored
Normal file
@@ -0,0 +1,668 @@
|
||||
use crate::config::Syntax;
|
||||
use crate::parser::{Expr, Node, Whitespace, Ws};
|
||||
|
||||
fn check_ws_split(s: &str, res: &(&str, &str, &str)) {
|
||||
match super::split_ws_parts(s) {
|
||||
Node::Lit(lws, s, rws) => {
|
||||
assert_eq!(lws, res.0);
|
||||
assert_eq!(s, res.1);
|
||||
assert_eq!(rws, res.2);
|
||||
}
|
||||
_ => {
|
||||
panic!("fail");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ws_splitter() {
|
||||
check_ws_split("", &("", "", ""));
|
||||
check_ws_split("a", &("", "a", ""));
|
||||
check_ws_split("\ta", &("\t", "a", ""));
|
||||
check_ws_split("b\n", &("", "b", "\n"));
|
||||
check_ws_split(" \t\r\n", &(" \t\r\n", "", ""));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_invalid_block() {
|
||||
super::parse("{% extend \"blah\" %}", &Syntax::default()).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_filter() {
|
||||
use Expr::*;
|
||||
let syntax = Syntax::default();
|
||||
assert_eq!(
|
||||
super::parse("{{ strvar|e }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(Ws(None, None), Filter("e", vec![Var("strvar")]),)],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{{ 2|abs }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(Ws(None, None), Filter("abs", vec![NumLit("2")]),)],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{{ -2|abs }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(
|
||||
Ws(None, None),
|
||||
Filter("abs", vec![Unary("-", NumLit("2").into())]),
|
||||
)],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{{ (1 - 2)|abs }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(
|
||||
Ws(None, None),
|
||||
Filter(
|
||||
"abs",
|
||||
vec![Group(
|
||||
BinOp("-", NumLit("1").into(), NumLit("2").into()).into()
|
||||
)]
|
||||
),
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_numbers() {
|
||||
let syntax = Syntax::default();
|
||||
assert_eq!(
|
||||
super::parse("{{ 2 }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(Ws(None, None), Expr::NumLit("2"),)],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{{ 2.5 }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(Ws(None, None), Expr::NumLit("2.5"),)],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_var() {
|
||||
let s = Syntax::default();
|
||||
|
||||
assert_eq!(
|
||||
super::parse("{{ foo }}", &s).unwrap(),
|
||||
vec![Node::Expr(Ws(None, None), Expr::Var("foo"))],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{{ foo_bar }}", &s).unwrap(),
|
||||
vec![Node::Expr(Ws(None, None), Expr::Var("foo_bar"))],
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
super::parse("{{ none }}", &s).unwrap(),
|
||||
vec![Node::Expr(Ws(None, None), Expr::Var("none"))],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_const() {
|
||||
let s = Syntax::default();
|
||||
|
||||
assert_eq!(
|
||||
super::parse("{{ FOO }}", &s).unwrap(),
|
||||
vec![Node::Expr(Ws(None, None), Expr::Path(vec!["FOO"]))],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{{ FOO_BAR }}", &s).unwrap(),
|
||||
vec![Node::Expr(Ws(None, None), Expr::Path(vec!["FOO_BAR"]))],
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
super::parse("{{ NONE }}", &s).unwrap(),
|
||||
vec![Node::Expr(Ws(None, None), Expr::Path(vec!["NONE"]))],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_path() {
|
||||
let s = Syntax::default();
|
||||
|
||||
assert_eq!(
|
||||
super::parse("{{ None }}", &s).unwrap(),
|
||||
vec![Node::Expr(Ws(None, None), Expr::Path(vec!["None"]))],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{{ Some(123) }}", &s).unwrap(),
|
||||
vec![Node::Expr(
|
||||
Ws(None, None),
|
||||
Expr::Call(
|
||||
Box::new(Expr::Path(vec!["Some"])),
|
||||
vec![Expr::NumLit("123")]
|
||||
),
|
||||
)],
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
super::parse("{{ Ok(123) }}", &s).unwrap(),
|
||||
vec![Node::Expr(
|
||||
Ws(None, None),
|
||||
Expr::Call(Box::new(Expr::Path(vec!["Ok"])), vec![Expr::NumLit("123")]),
|
||||
)],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{{ Err(123) }}", &s).unwrap(),
|
||||
vec![Node::Expr(
|
||||
Ws(None, None),
|
||||
Expr::Call(Box::new(Expr::Path(vec!["Err"])), vec![Expr::NumLit("123")]),
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_var_call() {
|
||||
assert_eq!(
|
||||
super::parse("{{ function(\"123\", 3) }}", &Syntax::default()).unwrap(),
|
||||
vec![Node::Expr(
|
||||
Ws(None, None),
|
||||
Expr::Call(
|
||||
Box::new(Expr::Var("function")),
|
||||
vec![Expr::StrLit("123"), Expr::NumLit("3")]
|
||||
),
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_path_call() {
|
||||
let s = Syntax::default();
|
||||
|
||||
assert_eq!(
|
||||
super::parse("{{ Option::None }}", &s).unwrap(),
|
||||
vec![Node::Expr(
|
||||
Ws(None, None),
|
||||
Expr::Path(vec!["Option", "None"])
|
||||
)],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{{ Option::Some(123) }}", &s).unwrap(),
|
||||
vec![Node::Expr(
|
||||
Ws(None, None),
|
||||
Expr::Call(
|
||||
Box::new(Expr::Path(vec!["Option", "Some"])),
|
||||
vec![Expr::NumLit("123")],
|
||||
),
|
||||
)],
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
super::parse("{{ self::function(\"123\", 3) }}", &s).unwrap(),
|
||||
vec![Node::Expr(
|
||||
Ws(None, None),
|
||||
Expr::Call(
|
||||
Box::new(Expr::Path(vec!["self", "function"])),
|
||||
vec![Expr::StrLit("123"), Expr::NumLit("3")],
|
||||
),
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_root_path() {
|
||||
let syntax = Syntax::default();
|
||||
assert_eq!(
|
||||
super::parse("{{ std::string::String::new() }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(
|
||||
Ws(None, None),
|
||||
Expr::Call(
|
||||
Box::new(Expr::Path(vec!["std", "string", "String", "new"])),
|
||||
vec![]
|
||||
),
|
||||
)],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{{ ::std::string::String::new() }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(
|
||||
Ws(None, None),
|
||||
Expr::Call(
|
||||
Box::new(Expr::Path(vec!["", "std", "string", "String", "new"])),
|
||||
vec![]
|
||||
),
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn change_delimiters_parse_filter() {
|
||||
let syntax = Syntax {
|
||||
expr_start: "{=",
|
||||
expr_end: "=}",
|
||||
..Syntax::default()
|
||||
};
|
||||
|
||||
super::parse("{= strvar|e =}", &syntax).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_precedence() {
|
||||
use Expr::*;
|
||||
let syntax = Syntax::default();
|
||||
assert_eq!(
|
||||
super::parse("{{ a + b == c }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(
|
||||
Ws(None, None),
|
||||
BinOp(
|
||||
"==",
|
||||
BinOp("+", Var("a").into(), Var("b").into()).into(),
|
||||
Var("c").into(),
|
||||
)
|
||||
)],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{{ a + b * c - d / e }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(
|
||||
Ws(None, None),
|
||||
BinOp(
|
||||
"-",
|
||||
BinOp(
|
||||
"+",
|
||||
Var("a").into(),
|
||||
BinOp("*", Var("b").into(), Var("c").into()).into(),
|
||||
)
|
||||
.into(),
|
||||
BinOp("/", Var("d").into(), Var("e").into()).into(),
|
||||
)
|
||||
)],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{{ a * (b + c) / -d }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(
|
||||
Ws(None, None),
|
||||
BinOp(
|
||||
"/",
|
||||
BinOp(
|
||||
"*",
|
||||
Var("a").into(),
|
||||
Group(BinOp("+", Var("b").into(), Var("c").into()).into()).into()
|
||||
)
|
||||
.into(),
|
||||
Unary("-", Var("d").into()).into()
|
||||
)
|
||||
)],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{{ a || b && c || d && e }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(
|
||||
Ws(None, None),
|
||||
BinOp(
|
||||
"||",
|
||||
BinOp(
|
||||
"||",
|
||||
Var("a").into(),
|
||||
BinOp("&&", Var("b").into(), Var("c").into()).into(),
|
||||
)
|
||||
.into(),
|
||||
BinOp("&&", Var("d").into(), Var("e").into()).into(),
|
||||
)
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_associativity() {
|
||||
use Expr::*;
|
||||
let syntax = Syntax::default();
|
||||
assert_eq!(
|
||||
super::parse("{{ a + b + c }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(
|
||||
Ws(None, None),
|
||||
BinOp(
|
||||
"+",
|
||||
BinOp("+", Var("a").into(), Var("b").into()).into(),
|
||||
Var("c").into()
|
||||
)
|
||||
)],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{{ a * b * c }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(
|
||||
Ws(None, None),
|
||||
BinOp(
|
||||
"*",
|
||||
BinOp("*", Var("a").into(), Var("b").into()).into(),
|
||||
Var("c").into()
|
||||
)
|
||||
)],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{{ a && b && c }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(
|
||||
Ws(None, None),
|
||||
BinOp(
|
||||
"&&",
|
||||
BinOp("&&", Var("a").into(), Var("b").into()).into(),
|
||||
Var("c").into()
|
||||
)
|
||||
)],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{{ a + b - c + d }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(
|
||||
Ws(None, None),
|
||||
BinOp(
|
||||
"+",
|
||||
BinOp(
|
||||
"-",
|
||||
BinOp("+", Var("a").into(), Var("b").into()).into(),
|
||||
Var("c").into()
|
||||
)
|
||||
.into(),
|
||||
Var("d").into()
|
||||
)
|
||||
)],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{{ a == b != c > d > e == f }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(
|
||||
Ws(None, None),
|
||||
BinOp(
|
||||
"==",
|
||||
BinOp(
|
||||
">",
|
||||
BinOp(
|
||||
">",
|
||||
BinOp(
|
||||
"!=",
|
||||
BinOp("==", Var("a").into(), Var("b").into()).into(),
|
||||
Var("c").into()
|
||||
)
|
||||
.into(),
|
||||
Var("d").into()
|
||||
)
|
||||
.into(),
|
||||
Var("e").into()
|
||||
)
|
||||
.into(),
|
||||
Var("f").into()
|
||||
)
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_odd_calls() {
|
||||
use Expr::*;
|
||||
let syntax = Syntax::default();
|
||||
assert_eq!(
|
||||
super::parse("{{ a[b](c) }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(
|
||||
Ws(None, None),
|
||||
Call(
|
||||
Box::new(Index(Box::new(Var("a")), Box::new(Var("b")))),
|
||||
vec![Var("c")],
|
||||
),
|
||||
)],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{{ (a + b)(c) }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(
|
||||
Ws(None, None),
|
||||
Call(
|
||||
Box::new(Group(Box::new(BinOp(
|
||||
"+",
|
||||
Box::new(Var("a")),
|
||||
Box::new(Var("b"))
|
||||
)))),
|
||||
vec![Var("c")],
|
||||
),
|
||||
)],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{{ a + b(c) }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(
|
||||
Ws(None, None),
|
||||
BinOp(
|
||||
"+",
|
||||
Box::new(Var("a")),
|
||||
Box::new(Call(Box::new(Var("b")), vec![Var("c")])),
|
||||
),
|
||||
)],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{{ (-a)(b) }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(
|
||||
Ws(None, None),
|
||||
Call(
|
||||
Box::new(Group(Box::new(Unary("-", Box::new(Var("a")))))),
|
||||
vec![Var("b")],
|
||||
),
|
||||
)],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{{ -a(b) }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(
|
||||
Ws(None, None),
|
||||
Unary("-", Box::new(Call(Box::new(Var("a")), vec![Var("b")])),),
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_comments() {
|
||||
let s = &Syntax::default();
|
||||
|
||||
assert_eq!(
|
||||
super::parse("{##}", s).unwrap(),
|
||||
vec![Node::Comment(Ws(None, None))],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{#- #}", s).unwrap(),
|
||||
vec![Node::Comment(Ws(Some(Whitespace::Suppress), None))],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{# -#}", s).unwrap(),
|
||||
vec![Node::Comment(Ws(None, Some(Whitespace::Suppress)))],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{#--#}", s).unwrap(),
|
||||
vec![Node::Comment(Ws(
|
||||
Some(Whitespace::Suppress),
|
||||
Some(Whitespace::Suppress)
|
||||
))],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{#- foo\n bar -#}", s).unwrap(),
|
||||
vec![Node::Comment(Ws(
|
||||
Some(Whitespace::Suppress),
|
||||
Some(Whitespace::Suppress)
|
||||
))],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{#- foo\n {#- bar\n -#} baz -#}", s).unwrap(),
|
||||
vec![Node::Comment(Ws(
|
||||
Some(Whitespace::Suppress),
|
||||
Some(Whitespace::Suppress)
|
||||
))],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{#+ #}", s).unwrap(),
|
||||
vec![Node::Comment(Ws(Some(Whitespace::Preserve), None))],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{# +#}", s).unwrap(),
|
||||
vec![Node::Comment(Ws(None, Some(Whitespace::Preserve)))],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{#++#}", s).unwrap(),
|
||||
vec![Node::Comment(Ws(
|
||||
Some(Whitespace::Preserve),
|
||||
Some(Whitespace::Preserve)
|
||||
))],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{#+ foo\n bar +#}", s).unwrap(),
|
||||
vec![Node::Comment(Ws(
|
||||
Some(Whitespace::Preserve),
|
||||
Some(Whitespace::Preserve)
|
||||
))],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{#+ foo\n {#+ bar\n +#} baz -+#}", s).unwrap(),
|
||||
vec![Node::Comment(Ws(
|
||||
Some(Whitespace::Preserve),
|
||||
Some(Whitespace::Preserve)
|
||||
))],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{#~ #}", s).unwrap(),
|
||||
vec![Node::Comment(Ws(Some(Whitespace::Minimize), None))],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{# ~#}", s).unwrap(),
|
||||
vec![Node::Comment(Ws(None, Some(Whitespace::Minimize)))],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{#~~#}", s).unwrap(),
|
||||
vec![Node::Comment(Ws(
|
||||
Some(Whitespace::Minimize),
|
||||
Some(Whitespace::Minimize)
|
||||
))],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{#~ foo\n bar ~#}", s).unwrap(),
|
||||
vec![Node::Comment(Ws(
|
||||
Some(Whitespace::Minimize),
|
||||
Some(Whitespace::Minimize)
|
||||
))],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{#~ foo\n {#~ bar\n ~#} baz -~#}", s).unwrap(),
|
||||
vec![Node::Comment(Ws(
|
||||
Some(Whitespace::Minimize),
|
||||
Some(Whitespace::Minimize)
|
||||
))],
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
super::parse("{# foo {# bar #} {# {# baz #} qux #} #}", s).unwrap(),
|
||||
vec![Node::Comment(Ws(None, None))],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_tuple() {
|
||||
use super::Expr::*;
|
||||
let syntax = Syntax::default();
|
||||
assert_eq!(
|
||||
super::parse("{{ () }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(Ws(None, None), Tuple(vec![]),)],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{{ (1) }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(Ws(None, None), Group(Box::new(NumLit("1"))),)],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{{ (1,) }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(Ws(None, None), Tuple(vec![NumLit("1")]),)],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{{ (1, ) }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(Ws(None, None), Tuple(vec![NumLit("1")]),)],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{{ (1 ,) }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(Ws(None, None), Tuple(vec![NumLit("1")]),)],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{{ (1 , ) }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(Ws(None, None), Tuple(vec![NumLit("1")]),)],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{{ (1, 2) }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(
|
||||
Ws(None, None),
|
||||
Tuple(vec![NumLit("1"), NumLit("2")]),
|
||||
)],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{{ (1, 2,) }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(
|
||||
Ws(None, None),
|
||||
Tuple(vec![NumLit("1"), NumLit("2")]),
|
||||
)],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{{ (1, 2, 3) }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(
|
||||
Ws(None, None),
|
||||
Tuple(vec![NumLit("1"), NumLit("2"), NumLit("3")]),
|
||||
)],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{{ ()|abs }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(
|
||||
Ws(None, None),
|
||||
Filter("abs", vec![Tuple(vec![])]),
|
||||
)],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{{ () | abs }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(
|
||||
Ws(None, None),
|
||||
BinOp("|", Box::new(Tuple(vec![])), Box::new(Var("abs"))),
|
||||
)],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{{ (1)|abs }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(
|
||||
Ws(None, None),
|
||||
Filter("abs", vec![Group(Box::new(NumLit("1")))]),
|
||||
)],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{{ (1) | abs }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(
|
||||
Ws(None, None),
|
||||
BinOp(
|
||||
"|",
|
||||
Box::new(Group(Box::new(NumLit("1")))),
|
||||
Box::new(Var("abs"))
|
||||
),
|
||||
)],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{{ (1,)|abs }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(
|
||||
Ws(None, None),
|
||||
Filter("abs", vec![Tuple(vec![NumLit("1")])]),
|
||||
)],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{{ (1,) | abs }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(
|
||||
Ws(None, None),
|
||||
BinOp(
|
||||
"|",
|
||||
Box::new(Tuple(vec![NumLit("1")])),
|
||||
Box::new(Var("abs"))
|
||||
),
|
||||
)],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{{ (1, 2)|abs }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(
|
||||
Ws(None, None),
|
||||
Filter("abs", vec![Tuple(vec![NumLit("1"), NumLit("2")])]),
|
||||
)],
|
||||
);
|
||||
assert_eq!(
|
||||
super::parse("{{ (1, 2) | abs }}", &syntax).unwrap(),
|
||||
vec![Node::Expr(
|
||||
Ws(None, None),
|
||||
BinOp(
|
||||
"|",
|
||||
Box::new(Tuple(vec![NumLit("1"), NumLit("2")])),
|
||||
Box::new(Var("abs"))
|
||||
),
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_missing_space_after_kw() {
|
||||
let syntax = Syntax::default();
|
||||
let err = super::parse("{%leta=b%}", &syntax).unwrap_err();
|
||||
assert!(matches!(
|
||||
&*err.msg,
|
||||
"unable to parse template:\n\n\"{%leta=b%}\""
|
||||
));
|
||||
}
|
||||
1
third_party/rust/askama_escape/.cargo-checksum.json
vendored
Normal file
1
third_party/rust/askama_escape/.cargo-checksum.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"files":{"Cargo.toml":"a140f9df40d83c3f3c39864df0e272bde3e210ad9d37cf90342c45f137c5b1aa","LICENSE-APACHE":"87cb0d734c723c083e51c825930ff42bce28596b52dee15567f6b28f19c195e3","LICENSE-MIT":"df20e0180764bf5bd76f74d47bc9e8c0069a666401629c390003a1d5eba99c92","README.md":"f1c057bd94aff0d98bcd7267655bb8af4c9c81a643423c5948f711e199945905","benches/all.rs":"0e0458780fa24e55402b11fdbc6ef2191b399459461a9f909a516363e824c838","src/lib.rs":"5f96ad55ac916b63ef051373994c08a0bfaa3b85a5bf031a579dc23163c47267"},"package":"619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341"}
|
||||
33
third_party/rust/askama_escape/Cargo.toml
vendored
Normal file
33
third_party/rust/askama_escape/Cargo.toml
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
|
||||
#
|
||||
# When uploading crates to the registry Cargo will automatically
|
||||
# "normalize" Cargo.toml files for maximal compatibility
|
||||
# with all versions of Cargo and also rewrite `path` dependencies
|
||||
# to registry (e.g., crates.io) dependencies.
|
||||
#
|
||||
# If you are reading this file be aware that the original Cargo.toml
|
||||
# will likely look very different (and much more reasonable).
|
||||
# See Cargo.toml.orig for the original contents.
|
||||
|
||||
[package]
|
||||
edition = "2018"
|
||||
name = "askama_escape"
|
||||
version = "0.10.3"
|
||||
description = "Optimized HTML escaping code, extracted from Askama"
|
||||
homepage = "https://github.com/djc/askama"
|
||||
documentation = "https://docs.rs/askama_escape"
|
||||
readme = "README.md"
|
||||
keywords = ["html", "escaping"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
repository = "https://github.com/djc/askama"
|
||||
|
||||
[[bench]]
|
||||
name = "all"
|
||||
harness = false
|
||||
[dev-dependencies.criterion]
|
||||
version = "0.3"
|
||||
|
||||
[features]
|
||||
json = []
|
||||
[badges.maintenance]
|
||||
status = "actively-developed"
|
||||
9
third_party/rust/askama_escape/README.md
vendored
Normal file
9
third_party/rust/askama_escape/README.md
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
# askama_escape: escaping utilities for the Askama templating engine
|
||||
|
||||
[](https://docs.rs/askama_escape/)
|
||||
[](https://crates.io/crates/askama_escape)
|
||||
[](https://github.com/djc/askama/actions?query=workflow%3ACI)
|
||||
[](https://gitter.im/djc/askama)
|
||||
|
||||
This crate contains helper code for HTML escaping used by the
|
||||
[Askama](https://github.com/djc/askama) templating engine.
|
||||
@@ -1,5 +1,18 @@
|
||||
{
|
||||
const STRING_LONG: &str = r"
|
||||
#[macro_use]
|
||||
extern crate criterion;
|
||||
|
||||
use askama_escape::{Html, MarkupDisplay};
|
||||
use criterion::Criterion;
|
||||
|
||||
criterion_main!(benches);
|
||||
criterion_group!(benches, functions);
|
||||
|
||||
fn functions(c: &mut Criterion) {
|
||||
c.bench_function("Escaping", escaping);
|
||||
}
|
||||
|
||||
fn escaping(b: &mut criterion::Bencher<'_>) {
|
||||
let string_long = r#"
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris consequat tellus sit
|
||||
amet ornare fermentum. Etiam nec erat ante. In at metus a orci mollis scelerisque.
|
||||
Sed eget ultrices turpis, at sollicitudin erat. Integer hendrerit nec magna quis
|
||||
@@ -36,15 +49,11 @@
|
||||
suscipit leo, lacinia dignissim lacus. Sed eget volutpat mi. In eu bibendum neque. Pellentesque
|
||||
finibus velit a fermentum rhoncus. Maecenas leo purus, eleifend eu lacus a, condimentum sagittis
|
||||
justo.
|
||||
</p>";
|
||||
|
||||
const STRING_SHORT: &str = "Lorem ipsum dolor sit amet,<foo>bar&foo\"bar\\foo/bar";
|
||||
|
||||
const EMPTY: &str = "";
|
||||
|
||||
const NO_ESCAPE: &str = "Lorem ipsum dolor sit amet,";
|
||||
|
||||
const NO_ESCAPE_LONG: &str = r"
|
||||
</p>"#;
|
||||
let string_short = "Lorem ipsum dolor sit amet,<foo>bar&foo\"bar\\foo/bar";
|
||||
let empty = "";
|
||||
let no_escape = "Lorem ipsum dolor sit amet,";
|
||||
let no_escape_long = r#"
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin scelerisque eu urna in aliquet.
|
||||
Phasellus ac nulla a urna sagittis consequat id quis est. Nullam eu ex eget erat accumsan dictum
|
||||
ac lobortis urna. Etiam fermentum ut quam at dignissim. Curabitur vestibulum luctus tellus, sit
|
||||
@@ -56,14 +65,13 @@ lacus ipsum eget quam. Vivamus orci lorem, maximus ac mi eget, bibendum vulputat
|
||||
vestibulum dui hendrerit, vestibulum lacus sit amet, posuere erat. Vivamus euismod massa diam,
|
||||
vulputate euismod lectus vestibulum nec. Donec sit amet massa magna. Nunc ipsum nulla, euismod
|
||||
quis lacus at, gravida maximus elit. Duis tristique, nisl nullam.
|
||||
";
|
||||
"#;
|
||||
|
||||
const STRINGS: &[&str] = &[
|
||||
STRING_LONG,
|
||||
STRING_SHORT,
|
||||
EMPTY,
|
||||
NO_ESCAPE,
|
||||
NO_ESCAPE_LONG,
|
||||
];
|
||||
STRINGS
|
||||
b.iter(|| {
|
||||
format!("{}", MarkupDisplay::new_unsafe(string_long, Html));
|
||||
format!("{}", MarkupDisplay::new_unsafe(string_short, Html));
|
||||
format!("{}", MarkupDisplay::new_unsafe(empty, Html));
|
||||
format!("{}", MarkupDisplay::new_unsafe(no_escape, Html));
|
||||
format!("{}", MarkupDisplay::new_unsafe(no_escape_long, Html));
|
||||
});
|
||||
}
|
||||
239
third_party/rust/askama_escape/src/lib.rs
vendored
Normal file
239
third_party/rust/askama_escape/src/lib.rs
vendored
Normal file
@@ -0,0 +1,239 @@
|
||||
#![cfg_attr(not(any(feature = "json", test)), no_std)]
|
||||
#![deny(elided_lifetimes_in_paths)]
|
||||
#![deny(unreachable_pub)]
|
||||
|
||||
use core::fmt::{self, Display, Formatter, Write};
|
||||
use core::str;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct MarkupDisplay<E, T>
|
||||
where
|
||||
E: Escaper,
|
||||
T: Display,
|
||||
{
|
||||
value: DisplayValue<T>,
|
||||
escaper: E,
|
||||
}
|
||||
|
||||
impl<E, T> MarkupDisplay<E, T>
|
||||
where
|
||||
E: Escaper,
|
||||
T: Display,
|
||||
{
|
||||
pub fn new_unsafe(value: T, escaper: E) -> Self {
|
||||
Self {
|
||||
value: DisplayValue::Unsafe(value),
|
||||
escaper,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_safe(value: T, escaper: E) -> Self {
|
||||
Self {
|
||||
value: DisplayValue::Safe(value),
|
||||
escaper,
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn mark_safe(mut self) -> MarkupDisplay<E, T> {
|
||||
self.value = match self.value {
|
||||
DisplayValue::Unsafe(t) => DisplayValue::Safe(t),
|
||||
_ => self.value,
|
||||
};
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<E, T> Display for MarkupDisplay<E, T>
|
||||
where
|
||||
E: Escaper,
|
||||
T: Display,
|
||||
{
|
||||
fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
|
||||
match self.value {
|
||||
DisplayValue::Unsafe(ref t) => write!(
|
||||
EscapeWriter {
|
||||
fmt,
|
||||
escaper: &self.escaper
|
||||
},
|
||||
"{}",
|
||||
t
|
||||
),
|
||||
DisplayValue::Safe(ref t) => t.fmt(fmt),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct EscapeWriter<'a, E, W> {
|
||||
fmt: W,
|
||||
escaper: &'a E,
|
||||
}
|
||||
|
||||
impl<E, W> Write for EscapeWriter<'_, E, W>
|
||||
where
|
||||
W: Write,
|
||||
E: Escaper,
|
||||
{
|
||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||
self.escaper.write_escaped(&mut self.fmt, s)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn escape<E>(string: &str, escaper: E) -> Escaped<'_, E>
|
||||
where
|
||||
E: Escaper,
|
||||
{
|
||||
Escaped { string, escaper }
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Escaped<'a, E>
|
||||
where
|
||||
E: Escaper,
|
||||
{
|
||||
string: &'a str,
|
||||
escaper: E,
|
||||
}
|
||||
|
||||
impl<E> Display for Escaped<'_, E>
|
||||
where
|
||||
E: Escaper,
|
||||
{
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
self.escaper.write_escaped(fmt, self.string)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Html;
|
||||
|
||||
macro_rules! escaping_body {
|
||||
($start:ident, $i:ident, $fmt:ident, $bytes:ident, $quote:expr) => {{
|
||||
if $start < $i {
|
||||
$fmt.write_str(unsafe { str::from_utf8_unchecked(&$bytes[$start..$i]) })?;
|
||||
}
|
||||
$fmt.write_str($quote)?;
|
||||
$start = $i + 1;
|
||||
}};
|
||||
}
|
||||
|
||||
impl Escaper for Html {
|
||||
fn write_escaped<W>(&self, mut fmt: W, string: &str) -> fmt::Result
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
let bytes = string.as_bytes();
|
||||
let mut start = 0;
|
||||
for (i, b) in bytes.iter().enumerate() {
|
||||
if b.wrapping_sub(b'"') <= FLAG {
|
||||
match *b {
|
||||
b'<' => escaping_body!(start, i, fmt, bytes, "<"),
|
||||
b'>' => escaping_body!(start, i, fmt, bytes, ">"),
|
||||
b'&' => escaping_body!(start, i, fmt, bytes, "&"),
|
||||
b'"' => escaping_body!(start, i, fmt, bytes, """),
|
||||
b'\'' => escaping_body!(start, i, fmt, bytes, "'"),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
if start < bytes.len() {
|
||||
fmt.write_str(unsafe { str::from_utf8_unchecked(&bytes[start..]) })
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Text;
|
||||
|
||||
impl Escaper for Text {
|
||||
fn write_escaped<W>(&self, mut fmt: W, string: &str) -> fmt::Result
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
fmt.write_str(string)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
enum DisplayValue<T>
|
||||
where
|
||||
T: Display,
|
||||
{
|
||||
Safe(T),
|
||||
Unsafe(T),
|
||||
}
|
||||
|
||||
pub trait Escaper {
|
||||
fn write_escaped<W>(&self, fmt: W, string: &str) -> fmt::Result
|
||||
where
|
||||
W: Write;
|
||||
}
|
||||
|
||||
const FLAG: u8 = b'>' - b'"';
|
||||
|
||||
/// Escape chevrons, ampersand and apostrophes for use in JSON
|
||||
#[cfg(feature = "json")]
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct JsonEscapeBuffer(Vec<u8>);
|
||||
|
||||
#[cfg(feature = "json")]
|
||||
impl JsonEscapeBuffer {
|
||||
pub fn new() -> Self {
|
||||
Self(Vec::new())
|
||||
}
|
||||
|
||||
pub fn finish(self) -> String {
|
||||
unsafe { String::from_utf8_unchecked(self.0) }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "json")]
|
||||
impl std::io::Write for JsonEscapeBuffer {
|
||||
fn write(&mut self, bytes: &[u8]) -> std::io::Result<usize> {
|
||||
macro_rules! push_esc_sequence {
|
||||
($start:ident, $i:ident, $self:ident, $bytes:ident, $quote:expr) => {{
|
||||
if $start < $i {
|
||||
$self.0.extend_from_slice(&$bytes[$start..$i]);
|
||||
}
|
||||
$self.0.extend_from_slice($quote);
|
||||
$start = $i + 1;
|
||||
}};
|
||||
}
|
||||
|
||||
self.0.reserve(bytes.len());
|
||||
let mut start = 0;
|
||||
for (i, b) in bytes.iter().enumerate() {
|
||||
match *b {
|
||||
b'&' => push_esc_sequence!(start, i, self, bytes, br#"\u0026"#),
|
||||
b'\'' => push_esc_sequence!(start, i, self, bytes, br#"\u0027"#),
|
||||
b'<' => push_esc_sequence!(start, i, self, bytes, br#"\u003c"#),
|
||||
b'>' => push_esc_sequence!(start, i, self, bytes, br#"\u003e"#),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
if start < bytes.len() {
|
||||
self.0.extend_from_slice(&bytes[start..]);
|
||||
}
|
||||
Ok(bytes.len())
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> std::io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::string::ToString;
|
||||
|
||||
#[test]
|
||||
fn test_escape() {
|
||||
assert_eq!(escape("", Html).to_string(), "");
|
||||
assert_eq!(escape("<&>", Html).to_string(), "<&>");
|
||||
assert_eq!(escape("bla&", Html).to_string(), "bla&");
|
||||
assert_eq!(escape("<foo", Html).to_string(), "<foo");
|
||||
assert_eq!(escape("bla&h", Html).to_string(), "bla&h");
|
||||
}
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
{"files":{"Cargo.toml":"c64762e3ad81f92bf69f4fd17efc4b01b21e75b9bdde8ca94078500b6651c867","README.md":"69ccc6e378995b9d490d64e23b42ea1d7a9e3232e3dae6fabf1f955786a49931","build.rs":"c8d3c38c1208eea36224662b284d8daf3e7ad1b07d22d750524f3da1cc66ccca","src/errorsupport.udl":"8f8e5711913ffd1b515ec60028529768990df51001e6125d4b83c948b41c4466","src/handling.rs":"6e0568b18d426531cb2ae9967c8dd0d51ece5a065f68b15eeb308b995edaa167","src/lib.rs":"1e41747d06a0d032c9601df85dd6e95001e432ae95a75dcca859355cbadef3b0","src/macros.rs":"0d03f82fab20c96a182f941baf3fcf2a286b00fea871ee7fd8e339abc14f9522","src/redact.rs":"c9a4df1a87be68b15d583587bda941d4c60a1d0449e2d43ff99f3611a290a863","src/reporting.rs":"f4af35d5fb5bf0ebef6dc6595edac6351e1dae2bff989c18810480fae2202168","uniffi.toml":"af91bcd8e7b1fa3f475a5e556979ff23c57b338395e0b65abc1cb1a0ee823e23"},"package":null}
|
||||
{"files":{"Cargo.toml":"8eb17651996280a83f998c7c5199e0692e859389e86b33729c67801aff9f03bb","README.md":"69ccc6e378995b9d490d64e23b42ea1d7a9e3232e3dae6fabf1f955786a49931","build.rs":"c8d3c38c1208eea36224662b284d8daf3e7ad1b07d22d750524f3da1cc66ccca","src/errorsupport.udl":"8f8e5711913ffd1b515ec60028529768990df51001e6125d4b83c948b41c4466","src/handling.rs":"6e0568b18d426531cb2ae9967c8dd0d51ece5a065f68b15eeb308b995edaa167","src/lib.rs":"1e41747d06a0d032c9601df85dd6e95001e432ae95a75dcca859355cbadef3b0","src/macros.rs":"0d03f82fab20c96a182f941baf3fcf2a286b00fea871ee7fd8e339abc14f9522","src/redact.rs":"c9a4df1a87be68b15d583587bda941d4c60a1d0449e2d43ff99f3611a290a863","src/reporting.rs":"f4af35d5fb5bf0ebef6dc6595edac6351e1dae2bff989c18810480fae2202168","uniffi.toml":"af91bcd8e7b1fa3f475a5e556979ff23c57b338395e0b65abc1cb1a0ee823e23"},"package":null}
|
||||
7
third_party/rust/error-support/Cargo.toml
vendored
7
third_party/rust/error-support/Cargo.toml
vendored
@@ -48,8 +48,11 @@ version = "1.4"
|
||||
version = ">=0.11,<=0.12"
|
||||
|
||||
[dependencies.uniffi]
|
||||
version = "0.29.0"
|
||||
version = "0.28.2"
|
||||
|
||||
[build-dependencies.uniffi]
|
||||
version = "0.29.0"
|
||||
version = "0.28.2"
|
||||
features = ["build"]
|
||||
|
||||
[lints.clippy]
|
||||
empty-line-after-doc-comments = "allow"
|
||||
|
||||
File diff suppressed because one or more lines are too long
1030
third_party/rust/glean-core/Cargo.lock
generated
vendored
1030
third_party/rust/glean-core/Cargo.lock
generated
vendored
File diff suppressed because it is too large
Load Diff
29
third_party/rust/glean-core/Cargo.toml
vendored
29
third_party/rust/glean-core/Cargo.toml
vendored
@@ -13,7 +13,7 @@
|
||||
edition = "2021"
|
||||
rust-version = "1.76"
|
||||
name = "glean-core"
|
||||
version = "64.0.0"
|
||||
version = "63.1.0"
|
||||
authors = [
|
||||
"Jan-Erik Rediger <jrediger@mozilla.com>",
|
||||
"The Glean Team <glean-team@mozilla.com>",
|
||||
@@ -29,7 +29,6 @@ include = [
|
||||
"/uniffi.toml",
|
||||
"/build.rs",
|
||||
]
|
||||
autolib = false
|
||||
autobins = false
|
||||
autoexamples = false
|
||||
autotests = false
|
||||
@@ -41,17 +40,7 @@ license = "MPL-2.0"
|
||||
repository = "https://github.com/mozilla/glean"
|
||||
|
||||
[package.metadata.glean]
|
||||
glean-parser = "17.0.1"
|
||||
|
||||
[badges.circle-ci]
|
||||
branch = "main"
|
||||
repository = "mozilla/glean"
|
||||
|
||||
[badges.maintenance]
|
||||
status = "actively-developed"
|
||||
|
||||
[features]
|
||||
enable_env_logger = ["env_logger"]
|
||||
glean-parser = "16.1.0"
|
||||
|
||||
[lib]
|
||||
name = "glean_core"
|
||||
@@ -179,7 +168,7 @@ version = "1.0.4"
|
||||
version = "0.1.40"
|
||||
|
||||
[dependencies.uniffi]
|
||||
version = "0.29.0"
|
||||
version = "0.28.0"
|
||||
default-features = false
|
||||
|
||||
[dependencies.uuid]
|
||||
@@ -204,10 +193,13 @@ version = "0.4"
|
||||
version = "3.8.0"
|
||||
|
||||
[build-dependencies.uniffi]
|
||||
version = "0.29.0"
|
||||
version = "0.28.0"
|
||||
features = ["build"]
|
||||
default-features = false
|
||||
|
||||
[features]
|
||||
enable_env_logger = ["env_logger"]
|
||||
|
||||
[target.'cfg(target_os = "android")'.dependencies.android_logger]
|
||||
version = "0.12.0"
|
||||
default-features = false
|
||||
@@ -216,3 +208,10 @@ default-features = false
|
||||
version = "0.1.0"
|
||||
features = ["logger"]
|
||||
default-features = false
|
||||
|
||||
[badges.circle-ci]
|
||||
branch = "main"
|
||||
repository = "mozilla/glean"
|
||||
|
||||
[badges.maintenance]
|
||||
status = "actively-developed"
|
||||
|
||||
63
third_party/rust/glean-core/src/core/mod.rs
vendored
63
third_party/rust/glean-core/src/core/mod.rs
vendored
@@ -127,7 +127,7 @@ where
|
||||
/// ping_lifetime_max_time: 2000,
|
||||
/// };
|
||||
/// let mut glean = Glean::new(cfg).unwrap();
|
||||
/// let ping = PingType::new("sample", true, false, true, true, true, vec![], vec![], true, vec![]);
|
||||
/// let ping = PingType::new("sample", true, false, true, true, true, vec![], vec![], true);
|
||||
/// glean.register_ping_type(&ping);
|
||||
///
|
||||
/// let call_counter: CounterMetric = CounterMetric::new(CommonMetricData {
|
||||
@@ -277,11 +277,13 @@ impl Glean {
|
||||
// instantiate the core metrics.
|
||||
glean.on_upload_enabled();
|
||||
} else {
|
||||
// If upload is disabled, then clear the metrics
|
||||
// but do not send a deletion request ping.
|
||||
// If we have run before, and we have an old client_id,
|
||||
// do the full upload disabled operations to clear metrics
|
||||
// and send a deletion request ping.
|
||||
// If upload is disabled, and we've never run before, only set the
|
||||
// client_id to KNOWN_CLIENT_ID, but do not send a deletion request
|
||||
// ping.
|
||||
// If we have run before, and if the client_id is not equal to
|
||||
// the KNOWN_CLIENT_ID, do the full upload disabled operations to
|
||||
// clear metrics, set the client_id to KNOWN_CLIENT_ID, and send a
|
||||
// deletion request ping.
|
||||
match glean
|
||||
.core_metrics
|
||||
.client_id
|
||||
@@ -289,17 +291,7 @@ impl Glean {
|
||||
{
|
||||
None => glean.clear_metrics(),
|
||||
Some(uuid) => {
|
||||
if uuid == *KNOWN_CLIENT_ID {
|
||||
// Previously Glean kept the KNOWN_CLIENT_ID stored.
|
||||
// Let's ensure we erase it now.
|
||||
if let Some(data) = glean.data_store.as_ref() {
|
||||
_ = data.remove_single_metric(
|
||||
Lifetime::User,
|
||||
"glean_client_info",
|
||||
"client_id",
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if uuid != *KNOWN_CLIENT_ID {
|
||||
// Temporarily enable uploading so we can submit a
|
||||
// deletion request ping.
|
||||
glean.upload_enabled = true;
|
||||
@@ -588,6 +580,14 @@ impl Glean {
|
||||
// so that it can't be accessed until this function is done.
|
||||
let _lock = self.upload_manager.clear_ping_queue();
|
||||
|
||||
// There is only one metric that we want to survive after clearing all
|
||||
// metrics: first_run_date. Here, we store its value so we can restore
|
||||
// it after clearing the metrics.
|
||||
let existing_first_run_date = self
|
||||
.core_metrics
|
||||
.first_run_date
|
||||
.get_value(self, "glean_client_info");
|
||||
|
||||
// Clear any pending pings that follow `collection_enabled`.
|
||||
let ping_maker = PingMaker::new();
|
||||
let disabled_pings = self
|
||||
@@ -605,7 +605,8 @@ impl Glean {
|
||||
// the effect of resetting those to their initial values.
|
||||
if let Some(data) = self.data_store.as_ref() {
|
||||
_ = data.clear_lifetime_storage(Lifetime::User, "glean_internal_info");
|
||||
_ = data.remove_single_metric(Lifetime::User, "glean_client_info", "client_id");
|
||||
_ = data.clear_lifetime_storage(Lifetime::User, "glean_client_info");
|
||||
_ = data.clear_lifetime_storage(Lifetime::Application, "glean_client_info");
|
||||
for (ping_name, ping) in &self.ping_registry {
|
||||
if ping.follows_collection_enabled() {
|
||||
_ = data.clear_ping_lifetime_storage(ping_name);
|
||||
@@ -622,6 +623,32 @@ impl Glean {
|
||||
// StorageEngineManager), since doing so would mean we would have to have the
|
||||
// application tell us again which experiments are active if telemetry is
|
||||
// re-enabled.
|
||||
|
||||
{
|
||||
// We need to briefly set upload_enabled to true here so that `set`
|
||||
// is not a no-op. This is safe, since nothing on the Rust side can
|
||||
// run concurrently to this since we hold a mutable reference to the
|
||||
// Glean object. Additionally, the pending pings have been cleared
|
||||
// from disk, so the PingUploader can't wake up and start sending
|
||||
// pings.
|
||||
self.upload_enabled = true;
|
||||
|
||||
// Store a "dummy" KNOWN_CLIENT_ID in the client_id metric. This will
|
||||
// make it easier to detect if pings were unintentionally sent after
|
||||
// uploading is disabled.
|
||||
self.core_metrics
|
||||
.client_id
|
||||
.set_from_uuid_sync(self, *KNOWN_CLIENT_ID);
|
||||
|
||||
// Restore the first_run_date.
|
||||
if let Some(existing_first_run_date) = existing_first_run_date {
|
||||
self.core_metrics
|
||||
.first_run_date
|
||||
.set_sync_chrono(self, existing_first_run_date);
|
||||
}
|
||||
|
||||
self.upload_enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets the application ID as specified on instantiation.
|
||||
|
||||
@@ -826,6 +826,7 @@ impl Database {
|
||||
data: &BTreeMap<String, Metric>,
|
||||
) -> Result<()> {
|
||||
if self.ping_lifetime_threshold == 0 && self.ping_lifetime_max_time.is_zero() {
|
||||
log::trace!("Auto-flush disabled.");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
||||
16
third_party/rust/glean-core/src/glean.udl
vendored
16
third_party/rust/glean-core/src/glean.udl
vendored
@@ -108,7 +108,6 @@ dictionary PingRateLimit {
|
||||
};
|
||||
|
||||
// An enum representing the different logging levels for the `log` crate.
|
||||
[Remote]
|
||||
enum LevelFilter {
|
||||
"Off",
|
||||
"Error",
|
||||
@@ -215,8 +214,6 @@ dictionary PingRequest {
|
||||
boolean body_has_info_sections;
|
||||
// The ping's name. Likely also somewhere in `path`.
|
||||
string ping_name;
|
||||
// The capabilities required during this ping's upload.
|
||||
sequence<string> uploader_capabilities;
|
||||
};
|
||||
|
||||
// An enum representing the possible upload tasks to be performed by an uploader.
|
||||
@@ -226,7 +223,6 @@ interface PingUploadTask {
|
||||
//
|
||||
// * request: the ping request for upload
|
||||
Upload(PingRequest request);
|
||||
|
||||
// A flag signaling that the pending pings directories are not done being processed,
|
||||
// thus the requester should wait and come back later.
|
||||
//
|
||||
@@ -258,15 +254,6 @@ interface UploadResult {
|
||||
// * unused: _ignored_.
|
||||
UnrecoverableFailure(i8 unused);
|
||||
|
||||
// The uploader is not capable of uploading this request due to lack of or
|
||||
// mismatched capabilities.
|
||||
//
|
||||
// e.g. The ping requires upload over OHTTP,
|
||||
// but the uploader doesn't support OHTTP.
|
||||
//
|
||||
// * unused: _ignored_.
|
||||
Incapable(i8 unused);
|
||||
|
||||
// A HTTP response code.
|
||||
//
|
||||
// This can still indicate an error, depending on the status code.
|
||||
@@ -322,8 +309,7 @@ interface PingType {
|
||||
boolean enabled,
|
||||
sequence<string> schedules_pings,
|
||||
sequence<string> reason_codes,
|
||||
boolean follows_collection_enabled,
|
||||
sequence<string> uploader_capabilities
|
||||
boolean follows_collection_enabled
|
||||
);
|
||||
void submit(optional string? reason = null);
|
||||
|
||||
|
||||
@@ -172,7 +172,6 @@ impl UploadMetrics {
|
||||
Cow::from("status_code_unknown"),
|
||||
Cow::from("unrecoverable"),
|
||||
Cow::from("recoverable"),
|
||||
Cow::from("incapable"),
|
||||
]),
|
||||
),
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@ impl InternalPings {
|
||||
"inactive".to_string(),
|
||||
],
|
||||
true,
|
||||
vec![],
|
||||
),
|
||||
metrics: PingType::new(
|
||||
"metrics",
|
||||
@@ -53,7 +52,6 @@ impl InternalPings {
|
||||
"upgrade".to_string(),
|
||||
],
|
||||
true,
|
||||
vec![],
|
||||
),
|
||||
events: PingType::new(
|
||||
"events",
|
||||
@@ -69,7 +67,6 @@ impl InternalPings {
|
||||
"max_capacity".to_string(),
|
||||
],
|
||||
true,
|
||||
vec![],
|
||||
),
|
||||
deletion_request: PingType::new(
|
||||
"deletion-request",
|
||||
@@ -81,7 +78,6 @@ impl InternalPings {
|
||||
vec![],
|
||||
vec!["at_init".to_string(), "set_upload_enabled".to_string()],
|
||||
true,
|
||||
vec![],
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
37
third_party/rust/glean-core/src/lib.rs
vendored
37
third_party/rust/glean-core/src/lib.rs
vendored
@@ -2,7 +2,6 @@
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
#![allow(clippy::doc_overindented_list_items)]
|
||||
#![allow(clippy::significant_drop_in_scrutinee)]
|
||||
#![allow(clippy::uninlined_format_args)]
|
||||
#![deny(rustdoc::broken_intra_doc_links)]
|
||||
@@ -412,7 +411,7 @@ fn initialize_inner(
|
||||
// The debug view tag might have been set before initialize,
|
||||
// get the cached value and set it.
|
||||
let debug_tag = PRE_INIT_DEBUG_VIEW_TAG.lock().unwrap();
|
||||
if !debug_tag.is_empty() {
|
||||
if debug_tag.len() > 0 {
|
||||
glean.set_debug_view_tag(&debug_tag);
|
||||
}
|
||||
|
||||
@@ -426,7 +425,7 @@ fn initialize_inner(
|
||||
// The source tags might have been set before initialize,
|
||||
// get the cached value and set them.
|
||||
let source_tags = PRE_INIT_SOURCE_TAGS.lock().unwrap();
|
||||
if !source_tags.is_empty() {
|
||||
if source_tags.len() > 0 {
|
||||
glean.set_source_tags(source_tags.to_vec());
|
||||
}
|
||||
|
||||
@@ -1307,19 +1306,31 @@ mod ffi {
|
||||
|
||||
type CowString = Cow<'static, str>;
|
||||
|
||||
uniffi::custom_type!(CowString, String, {
|
||||
remote,
|
||||
lower: |s| s.into_owned(),
|
||||
try_lift: |s| Ok(Cow::from(s))
|
||||
});
|
||||
impl UniffiCustomTypeConverter for CowString {
|
||||
type Builtin = String;
|
||||
|
||||
fn into_custom(val: Self::Builtin) -> uniffi::Result<Self> {
|
||||
Ok(Cow::from(val))
|
||||
}
|
||||
|
||||
fn from_custom(obj: Self) -> Self::Builtin {
|
||||
obj.into_owned()
|
||||
}
|
||||
}
|
||||
|
||||
type JsonValue = serde_json::Value;
|
||||
|
||||
uniffi::custom_type!(JsonValue, String, {
|
||||
remote,
|
||||
lower: |s| serde_json::to_string(&s).unwrap(),
|
||||
try_lift: |s| Ok(serde_json::from_str(&s)?)
|
||||
});
|
||||
impl UniffiCustomTypeConverter for JsonValue {
|
||||
type Builtin = String;
|
||||
|
||||
fn into_custom(val: Self::Builtin) -> uniffi::Result<Self> {
|
||||
Ok(serde_json::from_str(&val)?)
|
||||
}
|
||||
|
||||
fn from_custom(obj: Self) -> Self::Builtin {
|
||||
serde_json::to_string(&obj).unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
pub use ffi::*;
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@ pub fn new_glean(tempdir: Option<tempfile::TempDir>) -> (Glean, tempfile::TempDi
|
||||
vec![],
|
||||
vec![],
|
||||
true,
|
||||
vec![],
|
||||
);
|
||||
glean.register_ping_type(&ping);
|
||||
let ping = PingType::new_internal(
|
||||
@@ -48,7 +47,6 @@ pub fn new_glean(tempdir: Option<tempfile::TempDir>) -> (Glean, tempfile::TempDi
|
||||
vec![],
|
||||
vec![],
|
||||
true,
|
||||
vec![],
|
||||
);
|
||||
glean.register_ping_type(&ping);
|
||||
(glean, dir)
|
||||
@@ -350,11 +348,12 @@ fn client_id_is_managed_correctly_when_toggling_uploading() {
|
||||
|
||||
glean.set_upload_enabled(false);
|
||||
assert_eq!(
|
||||
None,
|
||||
*KNOWN_CLIENT_ID,
|
||||
glean
|
||||
.core_metrics
|
||||
.client_id
|
||||
.get_value(&glean, "glean_client_info")
|
||||
.unwrap()
|
||||
);
|
||||
|
||||
glean.set_upload_enabled(true);
|
||||
@@ -368,17 +367,18 @@ fn client_id_is_managed_correctly_when_toggling_uploading() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn client_id_is_not_set_when_uploading_disabled_at_start() {
|
||||
fn client_id_is_set_to_known_value_when_uploading_disabled_at_start() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let tmpname = dir.path().display().to_string();
|
||||
let glean = Glean::with_options(&tmpname, GLOBAL_APPLICATION_ID, false, true);
|
||||
|
||||
assert_eq!(
|
||||
None,
|
||||
*KNOWN_CLIENT_ID,
|
||||
glean
|
||||
.core_metrics
|
||||
.client_id
|
||||
.get_value(&glean, "glean_client_info")
|
||||
.unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1218,7 +1218,6 @@ fn disabled_pings_are_not_submitted() {
|
||||
vec![],
|
||||
vec![],
|
||||
true,
|
||||
vec![],
|
||||
);
|
||||
glean.register_ping_type(&ping);
|
||||
|
||||
@@ -1272,7 +1271,6 @@ fn pings_are_controllable_from_remote_settings_config() {
|
||||
vec![],
|
||||
vec![],
|
||||
true,
|
||||
vec![],
|
||||
);
|
||||
glean.register_ping_type(&disabled_ping);
|
||||
let enabled_ping = PingType::new(
|
||||
@@ -1285,7 +1283,6 @@ fn pings_are_controllable_from_remote_settings_config() {
|
||||
vec![],
|
||||
vec![],
|
||||
true,
|
||||
vec![],
|
||||
);
|
||||
glean.register_ping_type(&enabled_ping);
|
||||
|
||||
|
||||
15
third_party/rust/glean-core/src/metrics/ping.rs
vendored
15
third_party/rust/glean-core/src/metrics/ping.rs
vendored
@@ -40,9 +40,6 @@ struct InnerPing {
|
||||
/// True when it follows the `collection_enabled` flag (aka `upload_enabled`) flag.
|
||||
/// Otherwise it needs to be enabled through `enabled_pings`.
|
||||
follows_collection_enabled: AtomicBool,
|
||||
|
||||
/// Ordered list of uploader capabilities required to upload this ping.
|
||||
uploader_capabilities: Vec<String>,
|
||||
}
|
||||
|
||||
impl fmt::Debug for PingType {
|
||||
@@ -60,7 +57,6 @@ impl fmt::Debug for PingType {
|
||||
"follows_collection_enabled",
|
||||
&self.0.follows_collection_enabled.load(Ordering::Relaxed),
|
||||
)
|
||||
.field("uploader_capabilities", &self.0.uploader_capabilities)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
@@ -83,7 +79,6 @@ impl PingType {
|
||||
/// * `enabled` - Whether or not this ping is enabled. Note: Data that would be sent on a disabled
|
||||
/// ping will still be collected but is discarded rather than being submitted.
|
||||
/// * `reason_codes` - The valid reason codes for this ping.
|
||||
/// * `uploader_capabilities` - The ordered list of capabilities this ping requires to be uploaded with.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new<A: Into<String>>(
|
||||
name: A,
|
||||
@@ -95,7 +90,6 @@ impl PingType {
|
||||
schedules_pings: Vec<String>,
|
||||
reason_codes: Vec<String>,
|
||||
follows_collection_enabled: bool,
|
||||
uploader_capabilities: Vec<String>,
|
||||
) -> Self {
|
||||
Self::new_internal(
|
||||
name,
|
||||
@@ -107,7 +101,6 @@ impl PingType {
|
||||
schedules_pings,
|
||||
reason_codes,
|
||||
follows_collection_enabled,
|
||||
uploader_capabilities,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -122,7 +115,6 @@ impl PingType {
|
||||
schedules_pings: Vec<String>,
|
||||
reason_codes: Vec<String>,
|
||||
follows_collection_enabled: bool,
|
||||
uploader_capabilities: Vec<String>,
|
||||
) -> Self {
|
||||
let this = Self(Arc::new(InnerPing {
|
||||
name: name.into(),
|
||||
@@ -134,7 +126,6 @@ impl PingType {
|
||||
schedules_pings,
|
||||
reason_codes,
|
||||
follows_collection_enabled: AtomicBool::new(follows_collection_enabled),
|
||||
uploader_capabilities,
|
||||
}));
|
||||
|
||||
// Register this ping.
|
||||
@@ -231,11 +222,6 @@ impl PingType {
|
||||
&self.0.reason_codes
|
||||
}
|
||||
|
||||
/// The capabilities this ping requires to be uploaded under.
|
||||
pub fn uploader_capabilities(&self) -> &[String] {
|
||||
&self.0.uploader_capabilities
|
||||
}
|
||||
|
||||
/// Submits the ping for eventual uploading.
|
||||
///
|
||||
/// The ping content is assembled as soon as possible, but upload is not
|
||||
@@ -357,7 +343,6 @@ impl PingType {
|
||||
headers: Some(ping.headers),
|
||||
body_has_info_sections: self.0.include_info_sections,
|
||||
ping_name: self.0.name.to_string(),
|
||||
uploader_capabilities: self.0.uploader_capabilities.clone(),
|
||||
};
|
||||
|
||||
glean.upload_manager.enqueue_ping(glean, ping);
|
||||
|
||||
4
third_party/rust/glean-core/src/ping/mod.rs
vendored
4
third_party/rust/glean-core/src/ping/mod.rs
vendored
@@ -34,8 +34,6 @@ pub struct Ping<'a> {
|
||||
pub includes_info_sections: bool,
|
||||
/// Other pings that should be scheduled when this ping is sent.
|
||||
pub schedules_pings: Vec<String>,
|
||||
/// Capabilities the uploader must have in order to uplaoad this ping.
|
||||
pub uploader_capabilities: Vec<String>,
|
||||
}
|
||||
|
||||
/// Collect a ping's data, assemble it into its full payload and store it on disk.
|
||||
@@ -336,7 +334,6 @@ impl PingMaker {
|
||||
headers: self.get_headers(glean),
|
||||
includes_info_sections: ping.include_info_sections(),
|
||||
schedules_pings: ping.schedules_pings().to_vec(),
|
||||
uploader_capabilities: ping.uploader_capabilities().to_vec(),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -395,7 +392,6 @@ impl PingMaker {
|
||||
headers: Some(ping.headers.clone()),
|
||||
body_has_info_sections: Some(ping.includes_info_sections),
|
||||
ping_name: Some(ping.name.to_string()),
|
||||
uploader_capabilities: Some(ping.uploader_capabilities.clone()),
|
||||
};
|
||||
file.write_all(::serde_json::to_string(&metadata)?.as_bytes())?;
|
||||
}
|
||||
|
||||
@@ -30,8 +30,6 @@ pub struct PingPayload {
|
||||
pub body_has_info_sections: bool,
|
||||
/// The ping's name. (Also likely in the upload_path.)
|
||||
pub ping_name: String,
|
||||
/// The capabilities this ping must be uploaded under.
|
||||
pub uploader_capabilities: Vec<String>,
|
||||
}
|
||||
|
||||
/// A struct to hold the result of scanning all pings directories.
|
||||
@@ -88,8 +86,6 @@ pub struct PingMetadata {
|
||||
pub body_has_info_sections: Option<bool>,
|
||||
/// The name of the ping.
|
||||
pub ping_name: Option<String>,
|
||||
/// The capabilities this ping must be uploaded under.
|
||||
pub uploader_capabilities: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
/// Processes a ping's metadata.
|
||||
@@ -200,7 +196,6 @@ impl PingDirectoryManager {
|
||||
headers,
|
||||
body_has_info_sections,
|
||||
ping_name,
|
||||
uploader_capabilities,
|
||||
} = metadata
|
||||
.and_then(|m| process_metadata(&path, &m))
|
||||
.unwrap_or_default();
|
||||
@@ -213,7 +208,6 @@ impl PingDirectoryManager {
|
||||
headers,
|
||||
body_has_info_sections: body_has_info_sections.unwrap_or(true),
|
||||
ping_name,
|
||||
uploader_capabilities: uploader_capabilities.unwrap_or_default(),
|
||||
});
|
||||
} else {
|
||||
log::warn!(
|
||||
@@ -343,18 +337,7 @@ mod test {
|
||||
let (mut glean, dir) = new_glean(None);
|
||||
|
||||
// Register a ping for testing
|
||||
let ping_type = PingType::new(
|
||||
"test",
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
vec![],
|
||||
vec![],
|
||||
true,
|
||||
vec![],
|
||||
);
|
||||
let ping_type = PingType::new("test", true, true, true, true, true, vec![], vec![], true);
|
||||
glean.register_ping_type(&ping_type);
|
||||
|
||||
// Submit the ping to populate the pending_pings directory
|
||||
@@ -381,18 +364,7 @@ mod test {
|
||||
let (mut glean, dir) = new_glean(None);
|
||||
|
||||
// Register a ping for testing
|
||||
let ping_type = PingType::new(
|
||||
"test",
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
vec![],
|
||||
vec![],
|
||||
true,
|
||||
vec![],
|
||||
);
|
||||
let ping_type = PingType::new("test", true, true, true, true, true, vec![], vec![], true);
|
||||
glean.register_ping_type(&ping_type);
|
||||
|
||||
// Submit the ping to populate the pending_pings directory
|
||||
@@ -428,18 +400,7 @@ mod test {
|
||||
let (mut glean, dir) = new_glean(None);
|
||||
|
||||
// Register a ping for testing
|
||||
let ping_type = PingType::new(
|
||||
"test",
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
vec![],
|
||||
vec![],
|
||||
true,
|
||||
vec![],
|
||||
);
|
||||
let ping_type = PingType::new("test", true, true, true, true, true, vec![], vec![], true);
|
||||
glean.register_ping_type(&ping_type);
|
||||
|
||||
// Submit the ping to populate the pending_pings directory
|
||||
|
||||
31
third_party/rust/glean-core/src/upload/mod.rs
vendored
31
third_party/rust/glean-core/src/upload/mod.rs
vendored
@@ -331,7 +331,6 @@ impl PingUploadManager {
|
||||
headers,
|
||||
body_has_info_sections,
|
||||
ping_name,
|
||||
uploader_capabilities,
|
||||
} = ping;
|
||||
let mut request = PingRequest::builder(
|
||||
&self.language_binding_name,
|
||||
@@ -341,8 +340,7 @@ impl PingUploadManager {
|
||||
.path(path)
|
||||
.body(body)
|
||||
.body_has_info_sections(body_has_info_sections)
|
||||
.ping_name(ping_name)
|
||||
.uploader_capabilities(uploader_capabilities);
|
||||
.ping_name(ping_name);
|
||||
|
||||
if let Some(headers) = headers {
|
||||
request = request.headers(headers);
|
||||
@@ -744,7 +742,7 @@ impl PingUploadManager {
|
||||
self.directory_manager.delete_file(document_id);
|
||||
}
|
||||
|
||||
UnrecoverableFailure { .. } | HttpStatus { code: 400..=499 } | Incapable { .. } => {
|
||||
UnrecoverableFailure { .. } | HttpStatus { code: 400..=499 } => {
|
||||
log::warn!(
|
||||
"Unrecoverable upload failure while attempting to send ping {}. Error was {:?}",
|
||||
document_id,
|
||||
@@ -891,7 +889,6 @@ mod test {
|
||||
headers: None,
|
||||
body_has_info_sections: true,
|
||||
ping_name: "ping-name".into(),
|
||||
uploader_capabilities: vec![],
|
||||
},
|
||||
);
|
||||
|
||||
@@ -919,7 +916,6 @@ mod test {
|
||||
headers: None,
|
||||
body_has_info_sections: true,
|
||||
ping_name: "ping-name".into(),
|
||||
uploader_capabilities: vec![],
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -958,7 +954,6 @@ mod test {
|
||||
headers: None,
|
||||
body_has_info_sections: true,
|
||||
ping_name: "ping-name".into(),
|
||||
uploader_capabilities: vec![],
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -979,7 +974,6 @@ mod test {
|
||||
headers: None,
|
||||
body_has_info_sections: true,
|
||||
ping_name: "ping-name".into(),
|
||||
uploader_capabilities: vec![],
|
||||
},
|
||||
);
|
||||
|
||||
@@ -1013,7 +1007,6 @@ mod test {
|
||||
headers: None,
|
||||
body_has_info_sections: true,
|
||||
ping_name: "ping-name".into(),
|
||||
uploader_capabilities: vec![],
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -1043,7 +1036,6 @@ mod test {
|
||||
vec![],
|
||||
vec![],
|
||||
true,
|
||||
vec![],
|
||||
);
|
||||
glean.register_ping_type(&ping_type);
|
||||
|
||||
@@ -1086,7 +1078,6 @@ mod test {
|
||||
vec![],
|
||||
vec![],
|
||||
true,
|
||||
vec![],
|
||||
);
|
||||
glean.register_ping_type(&ping_type);
|
||||
|
||||
@@ -1127,7 +1118,6 @@ mod test {
|
||||
vec![],
|
||||
vec![],
|
||||
true,
|
||||
vec![],
|
||||
);
|
||||
glean.register_ping_type(&ping_type);
|
||||
|
||||
@@ -1168,7 +1158,6 @@ mod test {
|
||||
vec![],
|
||||
vec![],
|
||||
true,
|
||||
vec![],
|
||||
);
|
||||
glean.register_ping_type(&ping_type);
|
||||
|
||||
@@ -1209,7 +1198,6 @@ mod test {
|
||||
vec![],
|
||||
vec![],
|
||||
true,
|
||||
vec![],
|
||||
);
|
||||
glean.register_ping_type(&ping_type);
|
||||
|
||||
@@ -1252,7 +1240,6 @@ mod test {
|
||||
vec![],
|
||||
vec![],
|
||||
true,
|
||||
vec![],
|
||||
);
|
||||
glean.register_ping_type(&ping_type);
|
||||
|
||||
@@ -1303,7 +1290,6 @@ mod test {
|
||||
headers: None,
|
||||
body_has_info_sections: true,
|
||||
ping_name: "test-ping".into(),
|
||||
uploader_capabilities: vec![],
|
||||
},
|
||||
);
|
||||
|
||||
@@ -1324,7 +1310,6 @@ mod test {
|
||||
headers: None,
|
||||
body_has_info_sections: true,
|
||||
ping_name: "test-ping".into(),
|
||||
uploader_capabilities: vec![],
|
||||
},
|
||||
);
|
||||
|
||||
@@ -1373,7 +1358,6 @@ mod test {
|
||||
vec![],
|
||||
vec![],
|
||||
true,
|
||||
vec![],
|
||||
);
|
||||
glean.register_ping_type(&ping_type);
|
||||
|
||||
@@ -1410,7 +1394,6 @@ mod test {
|
||||
headers: None,
|
||||
body_has_info_sections: true,
|
||||
ping_name: "test-ping".into(),
|
||||
uploader_capabilities: vec![],
|
||||
},
|
||||
);
|
||||
upload_manager.enqueue_ping(
|
||||
@@ -1422,7 +1405,6 @@ mod test {
|
||||
headers: None,
|
||||
body_has_info_sections: true,
|
||||
ping_name: "test-ping".into(),
|
||||
uploader_capabilities: vec![],
|
||||
},
|
||||
);
|
||||
|
||||
@@ -1452,7 +1434,6 @@ mod test {
|
||||
vec![],
|
||||
vec![],
|
||||
true,
|
||||
vec![],
|
||||
);
|
||||
glean.register_ping_type(&ping_type);
|
||||
|
||||
@@ -1513,7 +1494,6 @@ mod test {
|
||||
vec![],
|
||||
vec![],
|
||||
true,
|
||||
vec![],
|
||||
);
|
||||
glean.register_ping_type(&ping_type);
|
||||
|
||||
@@ -1595,7 +1575,6 @@ mod test {
|
||||
vec![],
|
||||
vec![],
|
||||
true,
|
||||
vec![],
|
||||
);
|
||||
glean.register_ping_type(&ping_type);
|
||||
|
||||
@@ -1678,7 +1657,6 @@ mod test {
|
||||
vec![],
|
||||
vec![],
|
||||
true,
|
||||
vec![],
|
||||
);
|
||||
glean.register_ping_type(&ping_type);
|
||||
|
||||
@@ -1763,7 +1741,6 @@ mod test {
|
||||
vec![],
|
||||
vec![],
|
||||
true,
|
||||
vec![],
|
||||
);
|
||||
glean.register_ping_type(&ping_type);
|
||||
|
||||
@@ -1864,7 +1841,6 @@ mod test {
|
||||
headers: None,
|
||||
body_has_info_sections: true,
|
||||
ping_name: "ping-name".into(),
|
||||
uploader_capabilities: vec![],
|
||||
},
|
||||
);
|
||||
upload_manager.enqueue_ping(
|
||||
@@ -1876,7 +1852,6 @@ mod test {
|
||||
headers: None,
|
||||
body_has_info_sections: true,
|
||||
ping_name: "ping-name".into(),
|
||||
uploader_capabilities: vec![],
|
||||
},
|
||||
);
|
||||
|
||||
@@ -1942,7 +1917,6 @@ mod test {
|
||||
headers: None,
|
||||
body_has_info_sections: true,
|
||||
ping_name: "ping-name".into(),
|
||||
uploader_capabilities: vec![],
|
||||
};
|
||||
upload_manager.enqueue_ping(&glean, ping);
|
||||
assert!(upload_manager.get_upload_task(&glean, false).is_upload());
|
||||
@@ -1955,7 +1929,6 @@ mod test {
|
||||
headers: None,
|
||||
body_has_info_sections: true,
|
||||
ping_name: "ping-name".into(),
|
||||
uploader_capabilities: vec![],
|
||||
};
|
||||
upload_manager.enqueue_ping(&glean, ping);
|
||||
|
||||
|
||||
@@ -64,7 +64,6 @@ pub struct Builder {
|
||||
body_max_size: usize,
|
||||
body_has_info_sections: Option<bool>,
|
||||
ping_name: Option<String>,
|
||||
uploader_capabilities: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
impl Builder {
|
||||
@@ -92,7 +91,6 @@ impl Builder {
|
||||
body_max_size,
|
||||
body_has_info_sections: None,
|
||||
ping_name: None,
|
||||
uploader_capabilities: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,12 +166,6 @@ impl Builder {
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the required uploader capabilities.
|
||||
pub fn uploader_capabilities(mut self, uploader_capabilities: Vec<String>) -> Self {
|
||||
self.uploader_capabilities = Some(uploader_capabilities);
|
||||
self
|
||||
}
|
||||
|
||||
/// Consumes the builder and create a PingRequest.
|
||||
///
|
||||
/// # Panics
|
||||
@@ -204,9 +196,6 @@ impl Builder {
|
||||
ping_name: self
|
||||
.ping_name
|
||||
.expect("ping_name must be set before attempting to build PingRequest"),
|
||||
uploader_capabilities: self
|
||||
.uploader_capabilities
|
||||
.expect("uploader_capabilities must be set before attempting to build PingRequest"),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -229,8 +218,6 @@ pub struct PingRequest {
|
||||
pub body_has_info_sections: bool,
|
||||
/// The ping's name. Likely also somewhere in `path`.
|
||||
pub ping_name: String,
|
||||
/// The capabilities required during this ping's upload.
|
||||
pub uploader_capabilities: Vec<String>,
|
||||
}
|
||||
|
||||
impl PingRequest {
|
||||
@@ -293,7 +280,6 @@ mod test {
|
||||
.body("{}")
|
||||
.body_has_info_sections(false)
|
||||
.ping_name("whatevs")
|
||||
.uploader_capabilities(vec![])
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
|
||||
19
third_party/rust/glean-core/src/upload/result.rs
vendored
19
third_party/rust/glean-core/src/upload/result.rs
vendored
@@ -25,16 +25,6 @@ pub enum UploadResult {
|
||||
unused: i8,
|
||||
},
|
||||
|
||||
/// The uploader is not capable of uploading this request due to lack of or
|
||||
/// mismatched capabilities.
|
||||
///
|
||||
/// e.g. The ping requires upload over OHTTP, but the uploader doesn't support OHTTP.
|
||||
Incapable {
|
||||
#[doc(hidden)]
|
||||
/// Unused field. Required because UniFFI can't handle variants without fields.
|
||||
unused: i8,
|
||||
},
|
||||
|
||||
/// A HTTP response code.
|
||||
///
|
||||
/// This can still indicate an error, depending on the status code.
|
||||
@@ -65,7 +55,6 @@ impl UploadResult {
|
||||
UploadResult::HttpStatus { .. } => Some("status_code_unknown"),
|
||||
UploadResult::UnrecoverableFailure { .. } => Some("unrecoverable"),
|
||||
UploadResult::RecoverableFailure { .. } => Some("recoverable"),
|
||||
UploadResult::Incapable { .. } => Some("incapable"),
|
||||
UploadResult::Done { .. } => None,
|
||||
}
|
||||
}
|
||||
@@ -86,14 +75,6 @@ impl UploadResult {
|
||||
Self::UnrecoverableFailure { unused: 0 }
|
||||
}
|
||||
|
||||
/// The uploader is not capable of uploading this request due to lack of or
|
||||
/// mismatched capabilities.
|
||||
///
|
||||
/// e.g. The ping requires upload over OHTTP, but the uploader doesn't support OHTTP.
|
||||
pub fn incapable() -> Self {
|
||||
Self::Incapable { unused: 0 }
|
||||
}
|
||||
|
||||
/// A HTTP response code.
|
||||
///
|
||||
/// This can still indicate an error, depending on the status code.
|
||||
|
||||
@@ -12,18 +12,33 @@ use glean_core::Lifetime;
|
||||
|
||||
fn nofollows_ping(glean: &mut Glean) -> PingType {
|
||||
// When `follows_collection_enabled=false` then by default `enabled=false`
|
||||
let ping = PingBuilder::new("nofollows")
|
||||
.with_send_if_empty(true)
|
||||
.with_include_info_sections(false)
|
||||
.with_enabled(false)
|
||||
.with_follows_collection_enabled(false)
|
||||
.build();
|
||||
let ping = PingType::new(
|
||||
"nofollows",
|
||||
/* include_client_id */ false,
|
||||
/* send_if_empty */ true,
|
||||
/* precise_timestamps */ true,
|
||||
/* include_info_sections */ false,
|
||||
/* enabled */ false,
|
||||
vec![],
|
||||
vec![],
|
||||
/* follows_collection_enabled */ false,
|
||||
);
|
||||
glean.register_ping_type(&ping);
|
||||
ping
|
||||
}
|
||||
|
||||
fn manual_ping(glean: &mut Glean) -> PingType {
|
||||
let ping = PingBuilder::new("manual").build();
|
||||
let ping = PingType::new(
|
||||
"manual",
|
||||
/* include_client_id */ true,
|
||||
/* send_if_empty */ false,
|
||||
/* precise_timestamps */ true,
|
||||
/* include_info_sections */ true,
|
||||
/* enabled */ true,
|
||||
vec![],
|
||||
vec![],
|
||||
/* collection_enabled */ true,
|
||||
);
|
||||
glean.register_ping_type(&ping);
|
||||
ping
|
||||
}
|
||||
@@ -89,9 +104,17 @@ fn nofollows_ping_can_ride_along() {
|
||||
|
||||
let nofollows_ping = nofollows_ping(&mut glean);
|
||||
// Basically `manual_ping` but with a ride-along
|
||||
let manual_ping = PingBuilder::new("manual")
|
||||
.with_schedules_pings(vec!["nofollows".to_string()])
|
||||
.build();
|
||||
let manual_ping = PingType::new(
|
||||
"manual",
|
||||
/* include_client_id */ true,
|
||||
/* send_if_empty */ false,
|
||||
/* precise_timestamps */ true,
|
||||
/* include_info_sections */ true,
|
||||
/* enabled */ true,
|
||||
vec!["nofollows".to_string()],
|
||||
vec![],
|
||||
/* collection_enabled */ true,
|
||||
);
|
||||
glean.register_ping_type(&manual_ping);
|
||||
|
||||
// We need to store a metric as an empty ping is not stored.
|
||||
|
||||
77
third_party/rust/glean-core/tests/common/mod.rs
vendored
77
third_party/rust/glean-core/tests/common/mod.rs
vendored
@@ -78,86 +78,11 @@ pub fn new_glean(tempdir: Option<tempfile::TempDir>) -> (Glean, tempfile::TempDi
|
||||
}
|
||||
|
||||
pub fn new_test_ping(glean: &mut Glean, name: &str) -> PingType {
|
||||
let ping = PingBuilder::new(name).build();
|
||||
let ping = PingType::new(name, true, false, true, true, true, vec![], vec![], true);
|
||||
glean.register_ping_type(&ping);
|
||||
ping
|
||||
}
|
||||
|
||||
pub struct PingBuilder {
|
||||
name: String,
|
||||
include_client_id: bool,
|
||||
send_if_empty: bool,
|
||||
precise_timestamps: bool,
|
||||
include_info_sections: bool,
|
||||
enabled: bool,
|
||||
schedules_pings: Vec<String>,
|
||||
reason_codes: Vec<String>,
|
||||
follows_collection_enabled: bool,
|
||||
uploader_capabilities: Vec<String>,
|
||||
}
|
||||
|
||||
impl PingBuilder {
|
||||
pub fn new(name: &str) -> Self {
|
||||
Self {
|
||||
name: name.to_string(),
|
||||
include_client_id: true,
|
||||
send_if_empty: false,
|
||||
precise_timestamps: true,
|
||||
include_info_sections: true,
|
||||
enabled: true,
|
||||
schedules_pings: vec![],
|
||||
reason_codes: vec![],
|
||||
follows_collection_enabled: true,
|
||||
uploader_capabilities: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build(self) -> PingType {
|
||||
PingType::new(
|
||||
self.name,
|
||||
self.include_client_id,
|
||||
self.send_if_empty,
|
||||
self.precise_timestamps,
|
||||
self.include_info_sections,
|
||||
self.enabled,
|
||||
self.schedules_pings,
|
||||
self.reason_codes,
|
||||
self.follows_collection_enabled,
|
||||
self.uploader_capabilities,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn with_send_if_empty(mut self, value: bool) -> Self {
|
||||
self.send_if_empty = value;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_include_info_sections(mut self, value: bool) -> Self {
|
||||
self.include_info_sections = value;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_enabled(mut self, value: bool) -> Self {
|
||||
self.enabled = value;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_follows_collection_enabled(mut self, value: bool) -> Self {
|
||||
self.follows_collection_enabled = value;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_schedules_pings(mut self, value: Vec<String>) -> Self {
|
||||
self.schedules_pings = value;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_reasons(mut self, value: Vec<String>) -> Self {
|
||||
self.reason_codes = value;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts an iso8601::DateTime to a chrono::DateTime<FixedOffset>
|
||||
pub fn iso8601_to_chrono(datetime: &iso8601::DateTime) -> chrono::DateTime<chrono::FixedOffset> {
|
||||
if let YMD { year, month, day } = datetime.date {
|
||||
|
||||
56
third_party/rust/glean-core/tests/event.rs
vendored
56
third_party/rust/glean-core/tests/event.rs
vendored
@@ -163,11 +163,17 @@ fn test_sending_of_event_ping_when_it_fills_up() {
|
||||
let store_names: Vec<String> = vec!["events".into()];
|
||||
|
||||
for store_name in &store_names {
|
||||
glean.register_ping_type(
|
||||
&PingBuilder::new(store_name)
|
||||
.with_reasons(vec!["max_capacity".to_string()])
|
||||
.build(),
|
||||
);
|
||||
glean.register_ping_type(&PingType::new(
|
||||
store_name.clone(),
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
vec![],
|
||||
vec!["max_capacity".to_string()],
|
||||
true,
|
||||
));
|
||||
}
|
||||
|
||||
let click = EventMetric::new(
|
||||
@@ -225,11 +231,17 @@ fn test_server_knobs_config_changing_max_events() {
|
||||
let store_names: Vec<String> = vec!["events".into()];
|
||||
|
||||
for store_name in &store_names {
|
||||
glean.register_ping_type(
|
||||
&PingBuilder::new(store_name)
|
||||
.with_reasons(vec!["max_capacity".to_string()])
|
||||
.build(),
|
||||
);
|
||||
glean.register_ping_type(&PingType::new(
|
||||
store_name.clone(),
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
vec![],
|
||||
vec!["max_capacity".to_string()],
|
||||
true,
|
||||
));
|
||||
}
|
||||
|
||||
// 1. Set up an event to record
|
||||
@@ -501,7 +513,17 @@ fn event_storage_trimming() {
|
||||
let new_ping = |glean: &mut Glean, ping: &str| {
|
||||
// In Rust, pings are registered via construction.
|
||||
// But that's done asynchronously, so we do it synchronously here:
|
||||
glean.register_ping_type(&PingBuilder::new(ping).build());
|
||||
glean.register_ping_type(&PingType::new(
|
||||
ping.to_string(),
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
vec![],
|
||||
vec![],
|
||||
true,
|
||||
));
|
||||
};
|
||||
|
||||
// First, register both pings, so that we can record the event in the two pings.
|
||||
@@ -556,7 +578,17 @@ fn with_event_timestamps() {
|
||||
ping_lifetime_max_time: 0,
|
||||
};
|
||||
let mut glean = Glean::new(cfg).unwrap();
|
||||
let ping = PingBuilder::new("store1").build();
|
||||
let ping = PingType::new(
|
||||
"store1",
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
vec![],
|
||||
vec![],
|
||||
true,
|
||||
);
|
||||
glean.register_ping_type(&ping);
|
||||
|
||||
let store_name = "store1";
|
||||
|
||||
57
third_party/rust/glean-core/tests/ping.rs
vendored
57
third_party/rust/glean-core/tests/ping.rs
vendored
@@ -104,11 +104,29 @@ fn deletion_request_only_when_toggled_from_on_to_off() {
|
||||
fn empty_pings_with_flag_are_sent() {
|
||||
let (mut glean, _t) = new_glean(None);
|
||||
|
||||
let ping1 = PingBuilder::new("custom-ping1")
|
||||
.with_send_if_empty(true)
|
||||
.build();
|
||||
let ping1 = PingType::new(
|
||||
"custom-ping1",
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
vec![],
|
||||
vec![],
|
||||
true,
|
||||
);
|
||||
glean.register_ping_type(&ping1);
|
||||
let ping2 = PingBuilder::new("custom-ping2").build();
|
||||
let ping2 = PingType::new(
|
||||
"custom-ping2",
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
vec![],
|
||||
vec![],
|
||||
true,
|
||||
);
|
||||
glean.register_ping_type(&ping2);
|
||||
|
||||
// No data is stored in either of the custom pings
|
||||
@@ -145,7 +163,7 @@ fn test_pings_submitted_metric() {
|
||||
let metrics_ping = new_test_ping(&mut glean, "metrics");
|
||||
let baseline_ping = new_test_ping(&mut glean, "baseline");
|
||||
|
||||
let custom_ping = PingBuilder::new("custom").with_send_if_empty(true).build();
|
||||
let custom_ping = PingType::new("custom", true, true, true, true, true, vec![], vec![], true);
|
||||
glean.register_ping_type(&custom_ping);
|
||||
|
||||
// We need to store a metric as an empty ping is not stored.
|
||||
@@ -278,15 +296,30 @@ fn events_ping_with_metric_but_no_events_is_not_sent() {
|
||||
fn test_scheduled_pings_are_sent() {
|
||||
let (mut glean, _t) = new_glean(None);
|
||||
|
||||
let piggyback_ping = PingBuilder::new("piggyback")
|
||||
.with_send_if_empty(true)
|
||||
.build();
|
||||
let piggyback_ping = PingType::new(
|
||||
"piggyback",
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
vec![],
|
||||
vec![],
|
||||
true,
|
||||
);
|
||||
glean.register_ping_type(&piggyback_ping);
|
||||
|
||||
let trigger_ping = PingBuilder::new("trigger")
|
||||
.with_send_if_empty(true)
|
||||
.with_schedules_pings(vec!["piggyback".into()])
|
||||
.build();
|
||||
let trigger_ping = PingType::new(
|
||||
"trigger",
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
vec!["piggyback".into()],
|
||||
vec![],
|
||||
true,
|
||||
);
|
||||
glean.register_ping_type(&trigger_ping);
|
||||
|
||||
assert!(trigger_ping.submit_sync(&glean, None));
|
||||
|
||||
52
third_party/rust/glean-core/tests/ping_maker.rs
vendored
52
third_party/rust/glean-core/tests/ping_maker.rs
vendored
@@ -97,7 +97,17 @@ fn test_metrics_must_report_experimentation_id() {
|
||||
})
|
||||
.unwrap();
|
||||
let ping_maker = PingMaker::new();
|
||||
let ping_type = PingBuilder::new("store1").build();
|
||||
let ping_type = PingType::new(
|
||||
"store1",
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
vec![],
|
||||
vec![],
|
||||
true,
|
||||
);
|
||||
glean.register_ping_type(&ping_type);
|
||||
|
||||
// Record something, so the ping will have data
|
||||
@@ -154,7 +164,17 @@ fn experimentation_id_is_removed_if_send_if_empty_is_false() {
|
||||
.unwrap();
|
||||
let ping_maker = PingMaker::new();
|
||||
|
||||
let unknown_ping_type = PingBuilder::new("unknown").build();
|
||||
let unknown_ping_type = PingType::new(
|
||||
"unknown",
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
vec![],
|
||||
vec![],
|
||||
true,
|
||||
);
|
||||
glean.register_ping_type(&unknown_ping_type);
|
||||
|
||||
assert!(ping_maker
|
||||
@@ -170,7 +190,17 @@ fn collect_must_report_none_when_no_data_is_stored() {
|
||||
|
||||
let (mut glean, ping_maker, ping_type, _t) = set_up_basic_ping();
|
||||
|
||||
let unknown_ping_type = PingBuilder::new("unknown").build();
|
||||
let unknown_ping_type = PingType::new(
|
||||
"unknown",
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
vec![],
|
||||
vec![],
|
||||
true,
|
||||
);
|
||||
glean.register_ping_type(&ping_type);
|
||||
|
||||
assert!(ping_maker
|
||||
@@ -194,7 +224,17 @@ fn seq_number_must_be_sequential() {
|
||||
|
||||
for i in 0..=1 {
|
||||
for ping_name in ["store1", "store2"].iter() {
|
||||
let ping_type = PingBuilder::new(ping_name).build();
|
||||
let ping_type = PingType::new(
|
||||
*ping_name,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
vec![],
|
||||
vec![],
|
||||
true,
|
||||
);
|
||||
let ping = ping_maker
|
||||
.collect(&glean, &ping_type, None, "", "")
|
||||
.unwrap();
|
||||
@@ -279,7 +319,7 @@ fn no_pings_submitted_if_upload_disabled() {
|
||||
// Regression test, bug 1603571
|
||||
|
||||
let (mut glean, _t) = new_glean(None);
|
||||
let ping_type = PingBuilder::new("store1").with_send_if_empty(true).build();
|
||||
let ping_type = PingType::new("store1", true, true, true, true, true, vec![], vec![], true);
|
||||
glean.register_ping_type(&ping_type);
|
||||
|
||||
assert!(ping_type.submit_sync(&glean, None));
|
||||
@@ -297,7 +337,7 @@ fn no_pings_submitted_if_upload_disabled() {
|
||||
fn metadata_is_correctly_added_when_necessary() {
|
||||
let (mut glean, _t) = new_glean(None);
|
||||
glean.set_debug_view_tag("valid-tag");
|
||||
let ping_type = PingBuilder::new("store1").with_send_if_empty(true).build();
|
||||
let ping_type = PingType::new("store1", true, true, true, true, true, vec![], vec![], true);
|
||||
glean.register_ping_type(&ping_type);
|
||||
|
||||
assert!(ping_type.submit_sync(&glean, None));
|
||||
|
||||
2
third_party/rust/glean/.cargo-checksum.json
vendored
2
third_party/rust/glean/.cargo-checksum.json
vendored
@@ -1 +1 @@
|
||||
{"files":{"Cargo.lock":"e4d79c41440e41fe7d6aebfb531cd0f2d2459494fd1caac405c81313d5e16724","Cargo.toml":"8fe2df77137fdf166ce01926338d7f4d42811406b6c994984953e86ee6dfffc2","LICENSE":"1f256ecad192880510e84ad60474eab7589218784b9a50bc7ceee34c2b91f1d5","README.md":"5627cc81e6187ab6c2b4dff061af16d559edcab64ba786bac39daa69c703c595","src/common_test.rs":"c86cccfb7da1506cfed29cb2ee13d839b7ac7cffdfd70793c9665bb44e0b684f","src/configuration.rs":"de65ab99a26b4547be20803bc195cb50a6ab40b1a3f49a2e6230fed5a9d7a8d8","src/core_metrics.rs":"fef8fb4e5fa57c179836c6eb2cf59278fe3b8b036dbe57b0ff02971b4acd822f","src/lib.rs":"61b56a35c2bc6cd60bba2225b399881512d4b9a7d8cadca7fbed37ee6959d74c","src/net/http_uploader.rs":"0a94ac3cd87cb021529dee46d537765ab8d923e0f4ac7615225e878d3739e6dc","src/net/mod.rs":"09ba010b03d045fd8a2ccbe4f205c5275bb622bceb34cb81a0aa8f7d33804e2e","src/private/event.rs":"f299c79e4e2acb657f06004f3038bd8909e287719458566bc7f96262d8665e62","src/private/mod.rs":"66e90c41de74d1e80c5d3f49b8f1a86b8396be0b8c4a80f1a28903fe6d105ecf","src/private/object.rs":"7f17a7a658e8f7aa19a6bedf70f60f3f42713316d5d60298d682bb045caaafb7","src/private/ping.rs":"d2fb45e9e178ff6b17aa9c1b5258dfcd2ed91a2b43b44dec826de256ef5e8520","src/system.rs":"d602804a72258bfd65e51c571946631732ee27d81342d8aa406e47fdd241bbfa","src/test.rs":"bfbea9416dfdc96ebc1f9af5005b5b23f2285b74ef82c74cdab11635322ea3e3","tests/collection_enabled.rs":"3327a949dbdeec493d661261abda68ffa71acc50ab24cba4fde5302749e6f16b","tests/collection_enabled_bin.rs":"d3a6458b84012a447e5cb792f2292a06951ed252fad803b9166b437bacba542c","tests/common/mod.rs":"2fd391c5eb45f56fdfa3261dd631406c67ed36b10b0d5432febe2483da5c9d89","tests/custom_distribution_buffered.rs":"47c13d1f39adf3881e10caa19e0c08235f08958809e234bf37a79d37d7322cd5","tests/init_fails.rs":"ca7fa1b3dd6a21a9e005b7a4f0a18664c4bceb952dd463db8316500f72280d5b","tests/interruptible_shutdown.rs":"3d954bbe47d4f5fd103c51a4ff99f151662143c25c826da9734a00cd215909b9","tests/memory_distribution_buffered.rs":"db487475a5cf17a0864ccf150984ebdd28bf616573772cf678246cc1bdbcbc0f","tests/metric_metadata.rs":"05c947d3decf0a3281378dbb108080a05319ad8f130af5b07f9b049b80e5f04f","tests/near-empty-c0ffee-db.safe.bin":"89afb3bb8fc94430fb0ed0fe55f85f3f8bcc8fd0fed69a9df13cc560294ec9f5","tests/never_init.rs":"51fff5618f6603bc0945d70131698d10a1c6275f43bbc22a2de5807f8a79229f","tests/no_time_to_init.rs":"2ede23df6618ff1cb5ae3b7bbf95900ad0fd92072afa2e0319bf147b4f75cefc","tests/overflowing_preinit.rs":"985e140460a100986fd051ce901b787a3a7a9747a856cd06066b740ac7d2381c","tests/persist_ping_lifetime_nopanic.rs":"18379d3ffbf4a2c8c684c04ff7a0660b86dfbbb447db2d24dfed6073cb7ddf8f","tests/schema.rs":"23b49005402b914e55a0c5c155f30c2662c609f79be78d1385ec25b3600b3547","tests/simple.rs":"15c76a1b5a336fd6abfbdebafc971f5c6a9b75107ddbca65f0031cde3e2886da","tests/test-delayed-ping-data.sh":"4a6db98b4df6b77898ace6a8b4e8b4c60d3e5c44873bbf38c62e83583e27a3ff","tests/test-enabled-pings.sh":"06656e38f63e65475006b107dd6bd179b0cbaa1fad1470de38e679e91a9315a3","tests/test-pending-gets-removed.sh":"e335f2f00fa97a61b6d94e0005fb3b9de8c8db8076111a67ca47d85392039ea9","tests/test-ping-lifetime-flush.sh":"e8f118ea2f6fd973809e38d5e828a03cfccfe0b0f497ccde5ec92d6d1380c071","tests/test-shutdown-blocking.sh":"a44d8d4bbe2ee3ede9e48121150ae7a5386025160c5cef2181ca142232c5fb27","tests/test-thread-crashing.sh":"f3cd0cc8a7b4fe82bef0fe6fbfbbe45fbad6da3afe0f82578bc5cfb2d6527ac6","tests/timing_distribution_buffered.rs":"501f7289c0c28f0ab83838c88b058999b19436d0f2b693be0787513d7b67e06d","tests/timing_distribution_single_sample.rs":"4f9498b6ef29913da0356027efe5f572c81d2f426e8538c068b54a1cfa33c1b8","tests/upload_timing.rs":"b3b9db197bc2ec41556388969a6bf289e7ef19e05b9019bc2bd98c823fcf6ea3","tests/uploader_capabilities.rs":"347f19e534a50a211ea179d6818631270d1b4ec468098e6b6abcde1e4a6a9bca"},"package":"ba92338cfd9fb34b00c02c6da8e22936b41835eb02ab5462d3d88cc4b6249c35"}
|
||||
{"files":{"Cargo.lock":"d5243e925c951fc394126291886afc070712380f2faa93a68c3f571c7fccc105","Cargo.toml":"f86642423b6bb7faed3108bdf55e4add8e33ccb98dda8a15ede988db2b8fa974","LICENSE":"1f256ecad192880510e84ad60474eab7589218784b9a50bc7ceee34c2b91f1d5","README.md":"5627cc81e6187ab6c2b4dff061af16d559edcab64ba786bac39daa69c703c595","src/common_test.rs":"997f5331b719f82d86bb5e2f8e711da9cfb9433403e233c04a0ff39c3de5f7d0","src/configuration.rs":"de65ab99a26b4547be20803bc195cb50a6ab40b1a3f49a2e6230fed5a9d7a8d8","src/core_metrics.rs":"fef8fb4e5fa57c179836c6eb2cf59278fe3b8b036dbe57b0ff02971b4acd822f","src/lib.rs":"97d7d8001e091bd009e579ccb296a2355f523e5608e81e0485b3492347b40989","src/net/http_uploader.rs":"01ad5bd91384411a12c74434cd1c5cd585078cb34faba4615c70bdb669a9bccb","src/net/mod.rs":"5dff006240a6522e1db988514f22fb9361b3dece0c22fcf9eb8ff1b3308dd8f0","src/private/event.rs":"f299c79e4e2acb657f06004f3038bd8909e287719458566bc7f96262d8665e62","src/private/mod.rs":"66e90c41de74d1e80c5d3f49b8f1a86b8396be0b8c4a80f1a28903fe6d105ecf","src/private/object.rs":"7f17a7a658e8f7aa19a6bedf70f60f3f42713316d5d60298d682bb045caaafb7","src/private/ping.rs":"3b126183d4a5fdc200a9ded45c9a656d7d1e4c44e0d7e1c22f1b0e6968b07630","src/system.rs":"6eae5b41c15eba9cad6dbd116abe3519ee3e1fe034e79bdd692b029829a8c384","src/test.rs":"7c5f67bdce46bdb14b77cde0b716c2c2e0ab831e6c01b2e417c348c562289cac","tests/common/mod.rs":"68b0fca253f5c773cdb54d10a02d324d7c74ed5e16d4ba96387e4b643af2c0f3","tests/custom_distribution_buffered.rs":"47c13d1f39adf3881e10caa19e0c08235f08958809e234bf37a79d37d7322cd5","tests/init_fails.rs":"073b8c244ecbcae8e9cfc12cffd0629038bd978a4a4337073dbed6866023317b","tests/interruptible_shutdown.rs":"17b674c5960f3787ba0c51dc54f0c3759403427ad819985ad85f254e261002ab","tests/memory_distribution_buffered.rs":"db487475a5cf17a0864ccf150984ebdd28bf616573772cf678246cc1bdbcbc0f","tests/metric_metadata.rs":"05c947d3decf0a3281378dbb108080a05319ad8f130af5b07f9b049b80e5f04f","tests/never_init.rs":"fcbba9034f829eef0f54ff650f6442ad75cdd609bdd02f45472fd4456f8e3a66","tests/no_time_to_init.rs":"0a2027de97188a82f97ba6a45c75c740917eea4e1f4bd4b947b6da3da7c354ed","tests/overflowing_preinit.rs":"985e140460a100986fd051ce901b787a3a7a9747a856cd06066b740ac7d2381c","tests/persist_ping_lifetime_nopanic.rs":"18379d3ffbf4a2c8c684c04ff7a0660b86dfbbb447db2d24dfed6073cb7ddf8f","tests/schema.rs":"da8f808f7cfd42b0cefd5dd04ca87d514392476ba268a32c140d3293c9332caf","tests/simple.rs":"4991afdbd037e789af2325fb87dc4a1e0fbbfa63aa54f1f22dc8bf01190473c7","tests/test-delayed-ping-data.sh":"4a6db98b4df6b77898ace6a8b4e8b4c60d3e5c44873bbf38c62e83583e27a3ff","tests/test-enabled-pings.sh":"06656e38f63e65475006b107dd6bd179b0cbaa1fad1470de38e679e91a9315a3","tests/test-pending-gets-removed.sh":"e335f2f00fa97a61b6d94e0005fb3b9de8c8db8076111a67ca47d85392039ea9","tests/test-ping-lifetime-flush.sh":"e8f118ea2f6fd973809e38d5e828a03cfccfe0b0f497ccde5ec92d6d1380c071","tests/test-shutdown-blocking.sh":"a44d8d4bbe2ee3ede9e48121150ae7a5386025160c5cef2181ca142232c5fb27","tests/test-thread-crashing.sh":"f3cd0cc8a7b4fe82bef0fe6fbfbbe45fbad6da3afe0f82578bc5cfb2d6527ac6","tests/timing_distribution_buffered.rs":"501f7289c0c28f0ab83838c88b058999b19436d0f2b693be0787513d7b67e06d","tests/timing_distribution_single_sample.rs":"4f9498b6ef29913da0356027efe5f572c81d2f426e8538c068b54a1cfa33c1b8","tests/upload_timing.rs":"8b9ed65eaba3d51faf3cb62d1280d2737f234e0332615bfe6d9c60aab44b6560"},"package":"e2afa6754943cac5243099efd0d26e89cc8e06f1585776ba14ab0c6ee99e1f71"}
|
||||
335
third_party/rust/glean/Cargo.lock
generated
vendored
335
third_party/rust/glean/Cargo.lock
generated
vendored
@@ -28,9 +28,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.95"
|
||||
version = "1.0.71"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
|
||||
checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
|
||||
|
||||
[[package]]
|
||||
name = "arrayref"
|
||||
@@ -39,16 +39,48 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.4.0"
|
||||
name = "askama"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||
checksum = "47cbc3cf73fa8d9833727bbee4835ba5c421a0d65b72daf9a7b5d0e0f9cfb57e"
|
||||
dependencies = [
|
||||
"askama_derive",
|
||||
"askama_escape",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "askama_derive"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c22fbe0413545c098358e56966ff22cdd039e10215ae213cfbd65032b119fc94"
|
||||
dependencies = [
|
||||
"basic-toml",
|
||||
"mime",
|
||||
"mime_guess",
|
||||
"nom",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "askama_escape"
|
||||
version = "0.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "basic-toml"
|
||||
version = "0.1.9"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "823388e228f614e9558c6804262db37960ec8821856535f5c3f59913140558f8"
|
||||
checksum = "5c0de75129aa8d0cceaf750b89013f0e08804d6ec61416da787b35ad0d7cddf1"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
@@ -85,15 +117,41 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.9.0"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b"
|
||||
checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c"
|
||||
|
||||
[[package]]
|
||||
name = "camino"
|
||||
version = "1.1.9"
|
||||
version = "1.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3"
|
||||
checksum = "c530edf18f37068ac2d977409ed5cd50d53d73bc653c7647b48eb78976ac9ae2"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cargo-platform"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cbdb825da8a5df079a43676dbe042702f1707b1109f713a01420fbb4cc71fa27"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cargo_metadata"
|
||||
version = "0.15.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "982a0cf6a99c350d7246035613882e376d58cebe571785abc5da4f648d53ac0a"
|
||||
dependencies = [
|
||||
"camino",
|
||||
"cargo-platform",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
@@ -222,12 +280,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "fs-err"
|
||||
version = "2.11.0"
|
||||
version = "2.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88a41f105fe1d5b6b34b2055e3dc59bb79b46b48b2040b9e6c7b4b5de097aa41"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
checksum = "0845fa252299212f0389d64ba26f34fa32cfe41588355f21ed507c59a0f64541"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
@@ -242,7 +297,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "glean"
|
||||
version = "64.0.0"
|
||||
version = "63.1.0"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"env_logger",
|
||||
@@ -260,9 +315,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "glean-core"
|
||||
version = "64.0.0"
|
||||
version = "63.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92a2cbf41fbb9996b14fc1721b8bd06e669589de05e6efc20a24bab14285623a"
|
||||
checksum = "53cd53bb7a3b89b17d3989e95dd808b137ff47c504d1d19f14cb0d820cc2f42e"
|
||||
dependencies = [
|
||||
"android_logger",
|
||||
"bincode",
|
||||
@@ -284,15 +339,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.2"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2"
|
||||
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
|
||||
|
||||
[[package]]
|
||||
name = "goblin"
|
||||
version = "0.8.2"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b363a30c165f666402fe6a3024d3bec7ebc898f96a4a23bd1c99f8dbf3f4f47"
|
||||
checksum = "bb07a4ffed2093b118a525b1d8f5204ae274faed5604537caf7135d0f18d9887"
|
||||
dependencies = [
|
||||
"log",
|
||||
"plain",
|
||||
@@ -364,9 +419,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.14"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
|
||||
checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc"
|
||||
|
||||
[[package]]
|
||||
name = "json-pointer"
|
||||
@@ -415,27 +470,27 @@ checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.25"
|
||||
version = "0.4.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f"
|
||||
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.4"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "mime"
|
||||
version = "0.3.17"
|
||||
version = "0.3.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
||||
checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
|
||||
|
||||
[[package]]
|
||||
name = "mime_guess"
|
||||
version = "2.0.5"
|
||||
version = "2.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e"
|
||||
checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef"
|
||||
dependencies = [
|
||||
"mime",
|
||||
"unicase",
|
||||
@@ -458,9 +513,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "7.1.3"
|
||||
version = "7.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
||||
checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"minimal-lexical",
|
||||
@@ -497,9 +552,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.20.2"
|
||||
version = "1.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
|
||||
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
||||
|
||||
[[package]]
|
||||
name = "ordered-float"
|
||||
@@ -523,9 +578,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.15"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
|
||||
checksum = "cf1c2c742266c2f1041c914ba65355a83ae8747b05f208319784083583494b4b"
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
@@ -541,18 +596,18 @@ checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.93"
|
||||
version = "1.0.66"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99"
|
||||
checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.38"
|
||||
version = "1.0.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
|
||||
checksum = "5fe8a65d69dd0808184ebb5f836ab526bb259db23c657efa38711b1072ee47f0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
@@ -581,45 +636,6 @@ version = "0.6.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
|
||||
|
||||
[[package]]
|
||||
name = "rinja"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3dc4940d00595430b3d7d5a01f6222b5e5b51395d1120bdb28d854bb8abb17a5"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"rinja_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rinja_derive"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d9ed0146aef6e2825f1b1515f074510549efba38d71f4554eec32eb36ba18b"
|
||||
dependencies = [
|
||||
"basic-toml",
|
||||
"memchr",
|
||||
"mime",
|
||||
"mime_guess",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rinja_parser",
|
||||
"rustc-hash",
|
||||
"serde",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rinja_parser"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93f9a866e2e00a7a1fb27e46e9e324a6f7c0e7edc4543cae1d38f4e4a100c610"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"nom",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rkv"
|
||||
version = "0.19.0"
|
||||
@@ -642,12 +658,6 @@ dependencies = [
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.20"
|
||||
@@ -663,9 +673,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.19"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd"
|
||||
checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
|
||||
|
||||
[[package]]
|
||||
name = "scroll"
|
||||
@@ -688,19 +698,28 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.217"
|
||||
name = "semver"
|
||||
version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
|
||||
checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.179"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a5bf42b8d227d4abf38a1ddb08602e229108a517cd4e5bb28f9c7eaafdce5c0"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.217"
|
||||
version = "1.0.179"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
|
||||
checksum = "741e124f5485c7e60c03b043f79f320bff3527f4bbf12cf3831750dc46a0ec2c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -709,21 +728,20 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.138"
|
||||
version = "1.0.89"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949"
|
||||
checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
version = "0.3.11"
|
||||
version = "0.3.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
|
||||
checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de"
|
||||
|
||||
[[package]]
|
||||
name = "smawk"
|
||||
@@ -739,9 +757,9 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.98"
|
||||
version = "2.0.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1"
|
||||
checksum = "45c3457aacde3c65315de5031ec191ce46604304d2446e803d71ade03308d970"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -763,27 +781,27 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.16.1"
|
||||
version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9"
|
||||
checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d"
|
||||
dependencies = [
|
||||
"smawk",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.69"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
|
||||
checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.69"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
||||
checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -818,18 +836,21 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.5.11"
|
||||
version = "0.5.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
|
||||
checksum = "1333c76748e868a4d9d1017b5ab53171dfd095f70c712fdb4653a406547f598f"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicase"
|
||||
version = "2.8.1"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539"
|
||||
checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
|
||||
dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
@@ -839,9 +860,9 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.16"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034"
|
||||
checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
@@ -854,9 +875,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "uniffi"
|
||||
version = "0.29.0"
|
||||
version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba62a57e90f9baed5ad02a71a0870180fa1cc35499093b2d21be2edfb68ec0f7"
|
||||
checksum = "2db87def739fe4183947f8419d572d1849a4a09355eba4e988a2105cfd0ac6a7"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"uniffi_build",
|
||||
@@ -866,11 +887,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_bindgen"
|
||||
version = "0.29.0"
|
||||
version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2242f35214f1e0e3b47c495d340c69f649f9a9ece3a943a29e275686cc884533"
|
||||
checksum = "7a112599c9556d1581e4a3d72019a74c2c3e122cc27f4af12577a429c4d5e614"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"askama",
|
||||
"camino",
|
||||
"fs-err",
|
||||
"glob",
|
||||
@@ -878,7 +900,6 @@ dependencies = [
|
||||
"heck",
|
||||
"once_cell",
|
||||
"paste",
|
||||
"rinja",
|
||||
"serde",
|
||||
"textwrap",
|
||||
"toml",
|
||||
@@ -888,9 +909,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_build"
|
||||
version = "0.29.0"
|
||||
version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c887a6c9a2857d8dc2ab0c8d578e8aa4978145b4fd65ed44296341e89aebc3cc"
|
||||
checksum = "e2b12684401d2a8508ca9c72a95bbc45906417e42fc80942abaf033bbf01aa33"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"camino",
|
||||
@@ -898,34 +919,37 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_core"
|
||||
version = "0.29.0"
|
||||
name = "uniffi_checksum_derive"
|
||||
version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cad9fbdeb7ae4daf8d0f7704a3b638c37018eb16bb701e30fa17a2dd3e2d39c1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
"once_cell",
|
||||
"paste",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_internal_macros"
|
||||
version = "0.29.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22a9dba1d78b9ce429439891089c223478043d52a1c3176a0fcea2b5573a7fcf"
|
||||
checksum = "a22dbe67c1c957ac6e7611bdf605a6218aa86b0eebeb8be58b70ae85ad7d73dc"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_macros"
|
||||
version = "0.29.0"
|
||||
name = "uniffi_core"
|
||||
version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78dd5f8eefba5898b901086f5e7916da67b9a5286a01cc44e910cd75fa37c630"
|
||||
checksum = "5a0c35aaad30e3a9e6d4fe34e358d64dbc92ee09045b48591b05fc9f12e0905b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
"camino",
|
||||
"log",
|
||||
"once_cell",
|
||||
"paste",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_macros"
|
||||
version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db66474c5c61b0f7afc3b4995fecf9b72b340daa5ca0ef3da7778d75eb5482ea"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"camino",
|
||||
"fs-err",
|
||||
"once_cell",
|
||||
@@ -939,24 +963,39 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_meta"
|
||||
version = "0.29.0"
|
||||
version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d5965b1d4ffacef1eaa72fef9c00d2491641e87ad910f6c5859b9c503ddb16a"
|
||||
checksum = "d898893f102e0e39b8bcb7e3d2188f4156ba280db32db9e8af1f122d057e9526"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
"siphasher",
|
||||
"uniffi_internal_macros",
|
||||
"uniffi_checksum_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_testing"
|
||||
version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c6aa4f0cf9d12172d84fc00a35a6c1f3522b526daad05ae739f709f6941b9b6"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"camino",
|
||||
"cargo_metadata",
|
||||
"fs-err",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_udl"
|
||||
version = "0.29.0"
|
||||
version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "279b82bac9a382c796a0d210bb8354a0b813499b28aa1de046c85d78ca389805"
|
||||
checksum = "6b044e9c519e0bb51e516ab6f6d8f4f4dcf900ce30d5ad07c03f924e2824f28e"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"textwrap",
|
||||
"uniffi_meta",
|
||||
"uniffi_testing",
|
||||
"weedle2",
|
||||
]
|
||||
|
||||
@@ -980,6 +1019,12 @@ dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.10.0+wasi-snapshot-preview1"
|
||||
|
||||
31
third_party/rust/glean/Cargo.toml
vendored
31
third_party/rust/glean/Cargo.toml
vendored
@@ -13,7 +13,7 @@
|
||||
edition = "2021"
|
||||
rust-version = "1.76"
|
||||
name = "glean"
|
||||
version = "64.0.0"
|
||||
version = "63.1.0"
|
||||
authors = [
|
||||
"Jan-Erik Rediger <jrediger@mozilla.com>",
|
||||
"The Glean Team <glean-team@mozilla.com>",
|
||||
@@ -26,7 +26,6 @@ include = [
|
||||
"/tests",
|
||||
"/Cargo.toml",
|
||||
]
|
||||
autolib = false
|
||||
autobins = false
|
||||
autoexamples = false
|
||||
autotests = false
|
||||
@@ -40,25 +39,10 @@ keywords = [
|
||||
license = "MPL-2.0"
|
||||
repository = "https://github.com/mozilla/glean"
|
||||
|
||||
[badges.circle-ci]
|
||||
branch = "main"
|
||||
repository = "mozilla/glean"
|
||||
|
||||
[badges.maintenance]
|
||||
status = "actively-developed"
|
||||
|
||||
[lib]
|
||||
name = "glean"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[[test]]
|
||||
name = "collection_enabled"
|
||||
path = "tests/collection_enabled.rs"
|
||||
|
||||
[[test]]
|
||||
name = "collection_enabled_bin"
|
||||
path = "tests/collection_enabled_bin.rs"
|
||||
|
||||
[[test]]
|
||||
name = "custom_distribution_buffered"
|
||||
path = "tests/custom_distribution_buffered.rs"
|
||||
@@ -115,15 +99,11 @@ path = "tests/timing_distribution_single_sample.rs"
|
||||
name = "upload_timing"
|
||||
path = "tests/upload_timing.rs"
|
||||
|
||||
[[test]]
|
||||
name = "uploader_capabilities"
|
||||
path = "tests/uploader_capabilities.rs"
|
||||
|
||||
[dependencies.crossbeam-channel]
|
||||
version = "0.5"
|
||||
|
||||
[dependencies.glean-core]
|
||||
version = "64.0.0"
|
||||
version = "63.1.0"
|
||||
|
||||
[dependencies.inherent]
|
||||
version = "1"
|
||||
@@ -156,3 +136,10 @@ version = "1.0.44"
|
||||
|
||||
[dev-dependencies.tempfile]
|
||||
version = "3.1.0"
|
||||
|
||||
[badges.circle-ci]
|
||||
branch = "main"
|
||||
repository = "mozilla/glean"
|
||||
|
||||
[badges.maintenance]
|
||||
status = "actively-developed"
|
||||
|
||||
13
third_party/rust/glean/src/common_test.rs
vendored
13
third_party/rust/glean/src/common_test.rs
vendored
@@ -46,18 +46,7 @@ pub(crate) fn new_glean(
|
||||
.build(),
|
||||
};
|
||||
|
||||
_ = PingType::new(
|
||||
"store1",
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
vec![],
|
||||
vec![],
|
||||
true,
|
||||
vec![],
|
||||
);
|
||||
_ = PingType::new("store1", true, true, true, true, true, vec![], vec![], true);
|
||||
|
||||
crate::test_reset_glean(cfg, ClientInfoMetrics::unknown(), clear_stores);
|
||||
dir
|
||||
|
||||
2
third_party/rust/glean/src/lib.rs
vendored
2
third_party/rust/glean/src/lib.rs
vendored
@@ -23,7 +23,7 @@
|
||||
//! let cfg = ConfigurationBuilder::new(true, "/tmp/data", "org.mozilla.glean_core.example").build();
|
||||
//! glean::initialize(cfg, ClientInfoMetrics::unknown());
|
||||
//!
|
||||
//! let prototype_ping = PingType::new("prototype", true, true, true, true, true, vec!(), vec!(), true, vec![]);
|
||||
//! let prototype_ping = PingType::new("prototype", true, true, true, true, true, vec!(), vec!(), true);
|
||||
//!
|
||||
//! prototype_ping.submit(None);
|
||||
//! ```
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
use crate::net::{CapablePingUploadRequest, PingUploader, UploadResult};
|
||||
use crate::net::{PingUploadRequest, PingUploader, UploadResult};
|
||||
|
||||
/// A simple mechanism to upload pings over HTTPS.
|
||||
#[derive(Debug)]
|
||||
@@ -14,8 +14,7 @@ impl PingUploader for HttpUploader {
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `upload_request` - the requested upload.
|
||||
fn upload(&self, upload_request: CapablePingUploadRequest) -> UploadResult {
|
||||
let upload_request = upload_request.capable(|_| true).unwrap();
|
||||
fn upload(&self, upload_request: PingUploadRequest) -> UploadResult {
|
||||
log::debug!("TODO bug 1675468: submitting to {:?}", upload_request.url);
|
||||
UploadResult::http_status(200)
|
||||
}
|
||||
|
||||
26
third_party/rust/glean/src/net/mod.rs
vendored
26
third_party/rust/glean/src/net/mod.rs
vendored
@@ -34,26 +34,6 @@ pub struct PingUploadRequest {
|
||||
pub ping_name: String,
|
||||
}
|
||||
|
||||
/// A PingUploadRequest requiring proof of uploader capability.
|
||||
pub struct CapablePingUploadRequest {
|
||||
request: PingUploadRequest,
|
||||
capabilities: Vec<String>,
|
||||
}
|
||||
|
||||
impl CapablePingUploadRequest {
|
||||
/// If you are capable of satisfying this ping upload request's capabilities,
|
||||
/// obtain the PingUploadRequest.
|
||||
pub fn capable<F>(self, func: F) -> Option<PingUploadRequest>
|
||||
where
|
||||
F: FnOnce(Vec<String>) -> bool,
|
||||
{
|
||||
if func(self.capabilities) {
|
||||
return Some(self.request);
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// A description of a component used to upload pings.
|
||||
pub trait PingUploader: std::fmt::Debug + Send + Sync {
|
||||
/// Uploads a ping to a server.
|
||||
@@ -64,7 +44,7 @@ pub trait PingUploader: std::fmt::Debug + Send + Sync {
|
||||
/// * `body` - the serialized text data to send.
|
||||
/// * `headers` - a vector of tuples containing the headers to send with
|
||||
/// the request, i.e. (Name, Value).
|
||||
fn upload(&self, upload_request: CapablePingUploadRequest) -> UploadResult;
|
||||
fn upload(&self, upload_request: PingUploadRequest) -> UploadResult;
|
||||
}
|
||||
|
||||
/// The logic for uploading pings: this leaves the actual upload mechanism as
|
||||
@@ -152,10 +132,6 @@ impl UploadManager {
|
||||
body_has_info_sections: request.body_has_info_sections,
|
||||
ping_name: request.ping_name,
|
||||
};
|
||||
let upload_request = CapablePingUploadRequest {
|
||||
request: upload_request,
|
||||
capabilities: request.uploader_capabilities,
|
||||
};
|
||||
let result = inner.uploader.upload(upload_request);
|
||||
// Process the upload response.
|
||||
match glean_core::glean_process_ping_upload_response(doc_id, result) {
|
||||
|
||||
3
third_party/rust/glean/src/private/ping.rs
vendored
3
third_party/rust/glean/src/private/ping.rs
vendored
@@ -34,7 +34,6 @@ impl PingType {
|
||||
/// * `schedules_pings` - A list of pings which are triggered for submission when this ping is
|
||||
/// submitted.
|
||||
/// * `reason_codes` - The valid reason codes for this ping.
|
||||
/// * `uploader_capabilities` - The capabilities required during this ping's upload.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new<A: Into<String>>(
|
||||
name: A,
|
||||
@@ -46,7 +45,6 @@ impl PingType {
|
||||
schedules_pings: Vec<String>,
|
||||
reason_codes: Vec<String>,
|
||||
follows_collection_enabled: bool,
|
||||
uploader_capabilities: Vec<String>,
|
||||
) -> Self {
|
||||
let inner = glean_core::metrics::PingType::new(
|
||||
name.into(),
|
||||
@@ -58,7 +56,6 @@ impl PingType {
|
||||
schedules_pings,
|
||||
reason_codes,
|
||||
follows_collection_enabled,
|
||||
uploader_capabilities,
|
||||
);
|
||||
|
||||
Self {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user