uv: migrate to rkyv 0.8

Recently, rkyv 0.8 was released. Its API is a fair bit simpler now for
higher level uses (like for us in `uv`) and results in us being able to
delete a fair bit of code. This also removes our last dependency on `syn
1.0`, and thus drops that dependency.

Performance (via testing on the `transformers` example) seems to remain
about the same, which is what was expected:

```
$ hyperfine -w5 -r100 'uv lock' 'uv-ag-rkyv-update lock'
Benchmark 1: uv lock
  Time (mean ± σ):      55.6 ms ±   6.4 ms    [User: 30.4 ms, System: 35.1 ms]
  Range (min … max):    43.0 ms …  73.1 ms    100 runs

Benchmark 2: uv-ag-rkyv-update lock
  Time (mean ± σ):      56.5 ms ±   7.2 ms    [User: 30.5 ms, System: 36.3 ms]
  Range (min … max):    39.1 ms …  71.5 ms    100 runs

Summary
  uv lock ran
    1.02 ± 0.18 times faster than uv-ag-rkyv-update lock
```

Closes #7415
This commit is contained in:
Andrew Gallant 2024-09-18 13:44:57 -04:00 committed by Andrew Gallant
parent 91a574c6d2
commit 1379b530f6
22 changed files with 203 additions and 437 deletions

192
Cargo.lock generated
View file

@ -23,17 +23,6 @@ version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
[[package]]
name = "ahash"
version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9"
dependencies = [
"getrandom",
"once_cell",
"version_check",
]
[[package]]
name = "aho-corasick"
version = "1.1.3"
@ -201,7 +190,7 @@ checksum = "a27b8a3a6e1a44fa4c8baf1f653e4172e81486d4941f2237e20dc2d0cf4ddff1"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn",
]
[[package]]
@ -403,18 +392,6 @@ version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
[[package]]
name = "bitvec"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c"
dependencies = [
"funty",
"radium",
"tap",
"wyz",
]
[[package]]
name = "block-buffer"
version = "0.10.4"
@ -449,24 +426,25 @@ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
[[package]]
name = "bytecheck"
version = "0.6.12"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2"
checksum = "50c8f430744b23b54ad15161fcbc22d82a29b73eacbe425fea23ec822600bc6f"
dependencies = [
"bytecheck_derive",
"ptr_meta",
"rancor",
"simdutf8",
]
[[package]]
name = "bytecheck_derive"
version = "0.6.12"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659"
checksum = "523363cbe1df49b68215efdf500b103ac3b0fb4836aed6d15689a076eadb8fff"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
"syn",
]
[[package]]
@ -692,7 +670,7 @@ dependencies = [
"heck 0.5.0",
"proc-macro2",
"quote",
"syn 2.0.77",
"syn",
]
[[package]]
@ -932,7 +910,7 @@ checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf"
dependencies = [
"cfg-if",
"crossbeam-utils",
"hashbrown 0.14.5",
"hashbrown",
"lock_api",
"once_cell",
"parking_lot_core 0.9.10",
@ -1259,12 +1237,6 @@ dependencies = [
"winapi",
]
[[package]]
name = "funty"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
[[package]]
name = "futures"
version = "0.3.30"
@ -1334,7 +1306,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn",
]
[[package]]
@ -1476,15 +1448,6 @@ dependencies = [
"crunchy",
]
[[package]]
name = "hashbrown"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
dependencies = [
"ahash",
]
[[package]]
name = "hashbrown"
version = "0.14.5"
@ -1713,7 +1676,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5"
dependencies = [
"equivalent",
"hashbrown 0.14.5",
"hashbrown",
"serde",
]
@ -2150,7 +2113,7 @@ checksum = "dcf09caffaac8068c346b6df2a7fc27a177fd20b39421a39ce0a211bde679a6c"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn",
]
[[package]]
@ -2208,6 +2171,26 @@ dependencies = [
"windows-sys 0.48.0",
]
[[package]]
name = "munge"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64142d38c84badf60abf06ff9bd80ad2174306a5b11bd4706535090a30a419df"
dependencies = [
"munge_macro",
]
[[package]]
name = "munge_macro"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bb5c1d8184f13f7d0ccbeeca0def2f9a181bce2624302793005f5ca8aa62e5e"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "nanoid"
version = "0.4.0"
@ -2497,7 +2480,7 @@ dependencies = [
"pest_meta",
"proc-macro2",
"quote",
"syn 2.0.77",
"syn",
]
[[package]]
@ -2544,7 +2527,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn",
]
[[package]]
@ -2696,22 +2679,22 @@ dependencies = [
[[package]]
name = "ptr_meta"
version = "0.1.4"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1"
checksum = "fe9e76f66d3f9606f44e45598d155cb13ecf09f4a28199e48daf8c8fc937ea90"
dependencies = [
"ptr_meta_derive",
]
[[package]]
name = "ptr_meta_derive"
version = "0.1.4"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac"
checksum = "ca414edb151b4c8d125c12566ab0d74dc9cdba36fb80eb7b848c15f495fd32d1"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
"syn",
]
[[package]]
@ -2784,7 +2767,7 @@ dependencies = [
"proc-macro2",
"pyo3-macros-backend",
"quote",
"syn 2.0.77",
"syn",
]
[[package]]
@ -2797,7 +2780,7 @@ dependencies = [
"proc-macro2",
"pyo3-build-config",
"quote",
"syn 2.0.77",
"syn",
]
[[package]]
@ -2889,10 +2872,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "640c9bd8497b02465aeef5375144c26062e0dcd5939dfcbb0f5db76cb8c17c73"
[[package]]
name = "radium"
version = "0.7.0"
name = "rancor"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
checksum = "caf5f7161924b9d1cea0e4cabc97c372cea92b5f927fc13c6bca67157a0ad947"
dependencies = [
"ptr_meta",
]
[[package]]
name = "rand"
@ -3045,9 +3031,9 @@ checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
[[package]]
name = "rend"
version = "0.4.2"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c"
checksum = "a31c1f1959e4db12c985c0283656be0925f1539549db1e47c4bd0b8b599e1ef7"
dependencies = [
"bytecheck",
]
@ -3219,31 +3205,32 @@ dependencies = [
[[package]]
name = "rkyv"
version = "0.7.45"
version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9008cd6385b9e161d8229e1f6549dd23c3d022f132a2ea37ac3a10ac4935779b"
checksum = "395027076c569819ea6035ee62e664f5e03d74e281744f55261dd1afd939212b"
dependencies = [
"bitvec",
"bytecheck",
"bytes",
"hashbrown 0.12.3",
"hashbrown",
"indexmap",
"munge",
"ptr_meta",
"rancor",
"rend",
"rkyv_derive",
"seahash",
"tinyvec",
"uuid",
]
[[package]]
name = "rkyv_derive"
version = "0.7.45"
version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "503d1d27590a2b0a3a4ca4c94755aa2875657196ecbf401a42eff41d7de532c0"
checksum = "09cb82b74b4810f07e460852c32f522e979787691b0b7b7439fe473e49d49b2f"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
"syn",
]
[[package]]
@ -3459,7 +3446,7 @@ dependencies = [
"proc-macro2",
"quote",
"serde_derive_internals",
"syn 2.0.77",
"syn",
]
[[package]]
@ -3485,7 +3472,7 @@ checksum = "7f81c2fde025af7e69b1d1420531c8a8811ca898919db177141a85313b1cb932"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn",
]
[[package]]
@ -3540,7 +3527,7 @@ checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn",
]
[[package]]
@ -3551,7 +3538,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn",
]
[[package]]
@ -3776,17 +3763,6 @@ dependencies = [
"siphasher",
]
[[package]]
name = "syn"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "syn"
version = "2.0.77"
@ -3823,12 +3799,6 @@ version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eddb6b06d20fba9ed21fca3d696ee1b6e870bca0bcf9fa2971f6ae2436de576a"
[[package]]
name = "tap"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
[[package]]
name = "target-lexicon"
version = "0.12.16"
@ -3891,7 +3861,7 @@ dependencies = [
"cfg-if",
"proc-macro2",
"quote",
"syn 2.0.77",
"syn",
]
[[package]]
@ -3902,7 +3872,7 @@ checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn",
"test-case-core",
]
@ -3924,7 +3894,7 @@ checksum = "5999e24eaa32083191ba4e425deb75cdf25efefabe5aaccb7446dd0d4122a3f5"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn",
]
[[package]]
@ -3964,7 +3934,7 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn",
]
[[package]]
@ -4078,7 +4048,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn",
]
[[package]]
@ -4211,7 +4181,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn",
]
[[package]]
@ -4680,6 +4650,7 @@ dependencies = [
"async-trait",
"async_http_range_reader",
"async_zip",
"bytecheck",
"cache-key",
"distribution-filename",
"distribution-types",
@ -4963,7 +4934,7 @@ version = "0.0.1"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn",
"textwrap",
]
@ -5391,7 +5362,7 @@ dependencies = [
"once_cell",
"proc-macro2",
"quote",
"syn 2.0.77",
"syn",
"wasm-bindgen-shared",
]
@ -5425,7 +5396,7 @@ checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@ -5592,7 +5563,7 @@ checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn",
]
[[package]]
@ -5603,7 +5574,7 @@ checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn",
]
[[package]]
@ -5614,7 +5585,7 @@ checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn",
]
[[package]]
@ -5625,7 +5596,7 @@ checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn",
]
[[package]]
@ -5870,15 +5841,6 @@ dependencies = [
"url",
]
[[package]]
name = "wyz"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed"
dependencies = [
"tap",
]
[[package]]
name = "xattr"
version = "1.3.1"
@ -5929,7 +5891,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn",
]
[[package]]

View file

@ -70,6 +70,7 @@ axoupdater = { version = "0.7.2", default-features = false }
backoff = { version = "0.4.0" }
base64 = { version = "0.22.1" }
boxcar = { version = "0.2.5" }
bytecheck = { version = "0.8.0" }
cachedir = { version = "0.3.1" }
cargo-util = { version = "0.2.14" }
clap = { version = "4.5.17" }
@ -125,7 +126,7 @@ regex = { version = "1.10.6" }
reqwest = { version = "0.12.7", default-features = false, features = ["json", "gzip", "stream", "rustls-tls", "rustls-tls-native-roots", "socks"] }
reqwest-middleware = { git = "https://github.com/astral-sh/reqwest-middleware", rev = "5e3eaf254b5bd481c75d2710eed055f95b756913" }
reqwest-retry = { git = "https://github.com/astral-sh/reqwest-middleware", rev = "5e3eaf254b5bd481c75d2710eed055f95b756913" }
rkyv = { version = "0.7.45", features = ["strict", "validation"] }
rkyv = { version = "0.8.8", features = ["bytecheck"] }
rmp-serde = { version = "1.3.0" }
rust-netrc = { version = "0.1.1" }
rustc-hash = { version = "2.0.0" }

View file

@ -32,8 +32,7 @@ pub enum BuildTagError {
rkyv::Deserialize,
rkyv::Serialize,
)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
pub struct BuildTag(u64, Option<Arc<str>>);
impl FromStr for BuildTag {

View file

@ -25,8 +25,7 @@ pub enum DistExtension {
rkyv::Deserialize,
rkyv::Serialize,
)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
pub enum SourceDistExtension {
Zip,
TarGz,

View file

@ -20,8 +20,7 @@ use uv_normalize::{InvalidNameError, PackageName};
rkyv::Deserialize,
rkyv::Serialize,
)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
pub struct SourceDistFilename {
pub name: PackageName,
pub version: Version,

View file

@ -12,8 +12,7 @@ use uv_normalize::{InvalidNameError, PackageName};
use crate::{BuildTag, BuildTagError};
#[derive(Debug, Clone, Eq, PartialEq, Hash, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
pub struct WheelFilename {
pub name: PackageName,
pub version: Version,

View file

@ -24,8 +24,7 @@ pub enum FileConversionError {
#[derive(
Debug, Clone, Hash, Serialize, Deserialize, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize,
)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
pub struct File {
pub dist_info_metadata: bool,
pub filename: String,
@ -72,8 +71,7 @@ impl File {
#[derive(
Debug, Clone, Hash, Serialize, Deserialize, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize,
)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
pub enum FileLocation {
/// URL relative to the base URL.
RelativeUrl(String, String),
@ -150,8 +148,7 @@ impl Display for FileLocation {
rkyv::Serialize,
)]
#[serde(transparent)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
pub struct UrlString(String);
impl UrlString {

View file

@ -27,8 +27,7 @@ use std::{
rkyv::Deserialize,
rkyv::Serialize,
)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug, Eq, PartialEq, PartialOrd, Ord))]
#[rkyv(derive(Debug, Eq, PartialEq, PartialOrd, Ord))]
#[cfg_attr(feature = "pyo3", pyclass)]
pub enum Operator {
/// `== 1.2.3`
@ -288,15 +287,13 @@ impl std::fmt::Display for OperatorParseError {
/// let version = Version::from_str("1.19").unwrap();
/// ```
#[derive(Clone, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug, Eq, PartialEq, PartialOrd, Ord))]
#[rkyv(derive(Debug, Eq, PartialEq, PartialOrd, Ord))]
pub struct Version {
inner: Arc<VersionInner>,
}
#[derive(Clone, Debug, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug, Eq, PartialEq, PartialOrd, Ord))]
#[rkyv(derive(Debug, Eq, PartialEq, PartialOrd, Ord))]
enum VersionInner {
Small { small: VersionSmall },
Full { full: VersionFull },
@ -885,8 +882,7 @@ impl FromStr for Version {
/// Thankfully, such versions are incredibly rare. Virtually all versions have
/// zero or one pre, dev or post release components.
#[derive(Clone, Debug, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug, Eq, PartialEq, PartialOrd, Ord))]
#[rkyv(derive(Debug, Eq, PartialEq, PartialOrd, Ord))]
struct VersionSmall {
/// The representation discussed above.
repr: u64,
@ -1227,8 +1223,7 @@ impl VersionSmall {
/// In general, the "full" representation is rarely used in practice since most
/// versions will fit into the "small" representation.
#[derive(Clone, Debug, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug, Eq, PartialEq, PartialOrd, Ord))]
#[rkyv(derive(Debug, Eq, PartialEq, PartialOrd, Ord))]
struct VersionFull {
/// The [versioning
/// epoch](https://peps.python.org/pep-0440/#version-epochs). Normally
@ -1361,8 +1356,7 @@ impl FromStr for VersionPattern {
rkyv::Deserialize,
rkyv::Serialize,
)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug, Eq, PartialEq, PartialOrd, Ord))]
#[rkyv(derive(Debug, Eq, PartialEq, PartialOrd, Ord))]
#[cfg_attr(feature = "pyo3", pyclass)]
pub struct Prerelease {
/// The kind of pre-release.
@ -1387,8 +1381,7 @@ pub struct Prerelease {
rkyv::Deserialize,
rkyv::Serialize,
)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug, Eq, PartialEq, PartialOrd, Ord))]
#[rkyv(derive(Debug, Eq, PartialEq, PartialOrd, Ord))]
#[cfg_attr(feature = "pyo3", pyclass)]
pub enum PrereleaseKind {
/// alpha pre-release
@ -1431,8 +1424,7 @@ impl std::fmt::Display for Prerelease {
///
/// Luckily the default `Ord` implementation for `Vec<LocalSegment>` matches the PEP 440 rules.
#[derive(Eq, PartialEq, Debug, Clone, Hash, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug, Eq, PartialEq, PartialOrd, Ord))]
#[rkyv(derive(Debug, Eq, PartialEq, PartialOrd, Ord))]
pub enum LocalSegment {
/// Not-parseable as integer segment of local version
String(String),

View file

@ -47,8 +47,7 @@ use crate::{
rkyv::Deserialize,
rkyv::Serialize,
)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
#[cfg_attr(feature = "pyo3", pyclass(sequence))]
pub struct VersionSpecifiers(Vec<VersionSpecifier>);
@ -293,8 +292,7 @@ impl std::error::Error for VersionSpecifiersParseError {}
rkyv::Deserialize,
rkyv::Serialize,
)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
#[cfg_attr(feature = "pyo3", pyclass(get_all))]
pub struct VersionSpecifier {
/// ~=|==|!=|<=|>=|<|>|===, plus whether the version ended with a star

View file

@ -99,8 +99,7 @@ impl CoreMetadata {
rkyv::Deserialize,
rkyv::Serialize,
)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
#[serde(untagged)]
pub enum Yanked {
Bool(bool),
@ -303,8 +302,7 @@ impl FromStr for Hashes {
rkyv::Deserialize,
rkyv::Serialize,
)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
pub enum HashAlgorithm {
Md5,
Sha256,
@ -352,8 +350,7 @@ impl std::fmt::Display for HashAlgorithm {
rkyv::Deserialize,
rkyv::Serialize,
)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
pub struct HashDigest {
pub algorithm: HashAlgorithm,
pub digest: Box<str>,

View file

@ -766,7 +766,7 @@ impl CacheBucket {
Self::Interpreter => "interpreter-v2",
// Note that when bumping this, you'll also need to bump it
// in crates/uv/tests/cache_clean.rs.
Self::Simple => "simple-v12",
Self::Simple => "simple-v13",
Self::Wheels => "wheels-v1",
Self::Archive => "archive-v0",
Self::Builds => "builds-v0",

View file

@ -27,6 +27,7 @@ anyhow = { workspace = true }
async-trait = { workspace = true }
async_http_range_reader = { workspace = true }
async_zip = { workspace = true }
bytecheck = { workspace = true }
fs-err = { workspace = true, features = ["tokio"] }
futures = { workspace = true }
html-escape = { workspace = true }

View file

@ -75,9 +75,13 @@ impl<T: Serialize + DeserializeOwned> Cacheable for SerdeCacheable<T> {
/// All `OwnedArchive` values are cacheable.
impl<A> Cacheable for OwnedArchive<A>
where
A: rkyv::Archive + rkyv::Serialize<crate::rkyvutil::Serializer<4096>>,
A::Archived: for<'a> rkyv::CheckBytes<rkyv::validation::validators::DefaultValidator<'a>>
+ rkyv::Deserialize<A, rkyv::de::deserializers::SharedDeserializeMap>,
// A: rkyv::Archive + rkyv::Serialize<crate::rkyvutil::Serializer<4096>>,
// A::Archived: for<'a> rkyv::bytecheck::CheckBytes<rkyv::validation::validators::DefaultValidator<'a>>
// + rkyv::Deserialize<A, rkyv::de::deserializers::SharedDeserializeMap>,
A: rkyv::Archive + for<'a> rkyv::Serialize<crate::rkyvutil::Serializer<'a>>,
A::Archived: rkyv::Portable
+ rkyv::Deserialize<A, crate::rkyvutil::Deserializer>
+ for<'a> rkyv::bytecheck::CheckBytes<crate::rkyvutil::Validator<'a>>,
{
type Target = Self;

View file

@ -227,7 +227,7 @@ pub enum ErrorKind {
ArchiveRead(String),
#[error("Writing to cache archive failed: {0}")]
ArchiveWrite(#[source] crate::rkyvutil::SerializerError),
ArchiveWrite(String),
#[error("Network connectivity is disabled, but the requested data wasn't found in the cache for: `{0}`")]
Offline(String),

View file

@ -20,8 +20,7 @@ use crate::rkyvutil::OwnedArchive;
rkyv::Deserialize,
rkyv::Serialize,
)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
#[allow(clippy::struct_excessive_bools)]
pub struct CacheControl {
// directives for requests and responses

View file

@ -137,7 +137,7 @@ actually need to make an HTTP request).
use std::time::{Duration, SystemTime};
use {http::header::HeaderValue, rkyv::bytecheck};
use http::header::HeaderValue;
use crate::rkyvutil::OwnedArchive;
@ -151,12 +151,19 @@ mod control;
/// suspect we won't ever need to. We split them out into their own type so
/// that they can be shared between `CachePolicyBuilder` and `CachePolicy`.
#[derive(
Clone, Debug, Default, rkyv::Archive, rkyv::CheckBytes, rkyv::Deserialize, rkyv::Serialize,
Clone,
Debug,
Default,
rkyv::Archive,
rkyv::Deserialize,
rkyv::Portable,
rkyv::Serialize,
bytecheck::CheckBytes,
)]
// Since `CacheConfig` is so simple, we can use itself as the archived type.
// But note that this will fall apart if even something like an Option<u8> is
// added.
#[archive(as = "Self")]
#[rkyv(as = Self)]
#[repr(C)]
struct CacheConfig {
shared: bool,
@ -232,8 +239,7 @@ impl CachePolicyBuilder {
/// absent from this (among other things that uv probably doesn't care
/// about it) are proxy cache semantics.
#[derive(Debug, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
pub struct CachePolicy {
/// The configuration controlling the behavior of the cache.
config: CacheConfig,
@ -393,7 +399,7 @@ impl ArchivedCachePolicy {
if self.is_modified(&new_policy) {
AfterResponse::Modified(new_policy)
} else {
new_policy.response.status = self.response.status;
new_policy.response.status = self.response.status.into();
AfterResponse::NotModified(new_policy)
}
}
@ -522,7 +528,8 @@ impl ArchivedCachePolicy {
if let Some(&last_modified_unix_timestamp) =
self.response.headers.last_modified_unix_timestamp.as_ref()
{
if let Some(last_modified) = unix_timestamp_to_header(last_modified_unix_timestamp)
if let Some(last_modified) =
unix_timestamp_to_header(last_modified_unix_timestamp.into())
{
request
.headers_mut()
@ -696,7 +703,7 @@ impl ArchivedCachePolicy {
// ... we don't support any extensions.
//
// "a status code that is defined as heuristically cacheable"
if HEURISTICALLY_CACHEABLE_STATUS_CODES.contains(&self.response.status) {
if HEURISTICALLY_CACHEABLE_STATUS_CODES.contains(&self.response.status.into()) {
tracing::trace!(
"cached request {} is storable because its response has a \
heuristically cacheable status code {:?}",
@ -856,7 +863,7 @@ impl ArchivedCachePolicy {
.age(now)
.as_secs()
.saturating_sub(self.freshness_lifetime().as_secs());
if stale_amount <= max_stale {
if stale_amount <= max_stale.into() {
tracing::trace!(
"cached request {} has a cached response that allows staleness \
in this case because the stale amount is {} seconds and the \
@ -894,17 +901,13 @@ impl ArchivedCachePolicy {
/// [RFC 9111 S4.2.3]: https://www.rfc-editor.org/rfc/rfc9111.html#name-calculating-age
fn age(&self, now: SystemTime) -> Duration {
// RFC 9111 S4.2.3
let apparent_age = self
.response
.unix_timestamp
.saturating_sub(self.response.header_date());
let response_delay = self
.response
.unix_timestamp
.saturating_sub(self.request.unix_timestamp);
let apparent_age =
u64::from(self.response.unix_timestamp).saturating_sub(self.response.header_date());
let response_delay = u64::from(self.response.unix_timestamp)
.saturating_sub(self.request.unix_timestamp.into());
let corrected_age_value = self.response.header_age().saturating_add(response_delay);
let corrected_initial_age = apparent_age.max(corrected_age_value);
let resident_age = unix_timestamp(now).saturating_sub(self.response.unix_timestamp);
let resident_age = unix_timestamp(now).saturating_sub(self.response.unix_timestamp.into());
let current_age = corrected_initial_age + resident_age;
Duration::from_secs(current_age)
}
@ -921,7 +924,7 @@ impl ArchivedCachePolicy {
fn freshness_lifetime(&self) -> Duration {
if self.config.shared {
if let Some(&s_maxage) = self.response.headers.cc.s_maxage_seconds.as_ref() {
let duration = Duration::from_secs(s_maxage);
let duration = Duration::from_secs(s_maxage.into());
tracing::trace!(
"freshness lifetime found via shared \
cache-control max age setting: {duration:?}"
@ -930,14 +933,15 @@ impl ArchivedCachePolicy {
}
}
if let Some(&max_age) = self.response.headers.cc.max_age_seconds.as_ref() {
let duration = Duration::from_secs(max_age);
let duration = Duration::from_secs(max_age.into());
tracing::trace!(
"freshness lifetime found via cache-control max age setting: {duration:?}"
);
return duration;
}
if let Some(&expires) = self.response.headers.expires_unix_timestamp.as_ref() {
let duration = Duration::from_secs(expires.saturating_sub(self.response.header_date()));
let duration =
Duration::from_secs(u64::from(expires).saturating_sub(self.response.header_date()));
tracing::trace!("freshness lifetime found via expires header: {duration:?}");
return duration;
}
@ -1019,8 +1023,7 @@ pub enum AfterResponse {
}
#[derive(Debug, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
struct Request {
uri: String,
method: Method,
@ -1040,8 +1043,7 @@ impl<'a> From<&'a reqwest::Request> for Request {
}
#[derive(Debug, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
struct RequestHeaders {
/// The cache control directives from the `Cache-Control` header.
cc: CacheControl,
@ -1065,8 +1067,7 @@ impl<'a> From<&'a http::HeaderMap> for RequestHeaders {
/// cache. Instead, we treat them as "unrecognized" and consider the responses
/// not-storable.
#[derive(Debug, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
#[repr(u8)]
enum Method {
Get,
@ -1087,8 +1088,7 @@ impl<'a> From<&'a http::Method> for Method {
}
#[derive(Debug, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
struct Response {
status: u16,
headers: ResponseHeaders,
@ -1105,7 +1105,11 @@ impl ArchivedResponse {
///
/// [RFC 9111 S4.2.3]: https://www.rfc-editor.org/rfc/rfc9111.html#section-4.2.3
fn header_age(&self) -> u64 {
self.headers.age_seconds.unwrap_or(0)
self.headers
.age_seconds
.as_ref()
.map(u64::from)
.unwrap_or(0)
}
/// Returns the "date" header value on this response, with a fallback to
@ -1116,6 +1120,7 @@ impl ArchivedResponse {
self.headers
.date_unix_timestamp
.unwrap_or(self.unix_timestamp)
.into()
}
/// Returns true when this response has a status code that is considered
@ -1138,8 +1143,7 @@ impl<'a> From<&'a reqwest::Response> for Response {
}
#[derive(Debug, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
struct ResponseHeaders {
/// The directives from the `Cache-Control` header.
cc: CacheControl,
@ -1209,8 +1213,7 @@ impl<'a> From<&'a http::HeaderMap> for ResponseHeaders {
}
#[derive(Debug, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
struct ETag {
/// The actual `ETag` validator value.
///
@ -1267,8 +1270,7 @@ impl ETag {
/// [RFC 9110 S12.5.5]: https://www.rfc-editor.org/rfc/rfc9110#section-12.5.5
/// [RFC 9111 S4.1]: https://www.rfc-editor.org/rfc/rfc9111.html#section-4.1
#[derive(Debug, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
struct Vary {
fields: Vec<VaryField>,
}
@ -1349,8 +1351,7 @@ impl ArchivedVary {
///
/// [RFC 9111 S4.1]: https://www.rfc-editor.org/rfc/rfc9111.html#section-4.1
#[derive(Debug, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
struct VaryField {
name: String,
value: Vec<u8>,

View file

@ -7,7 +7,7 @@ pub use registry_client::{
Connectivity, RegistryClient, RegistryClientBuilder, SimpleMetadata, SimpleMetadatum,
VersionFiles,
};
pub use rkyvutil::OwnedArchive;
pub use rkyvutil::{Deserializer, OwnedArchive, Serializer, Validator};
mod base_client;
mod cached_client;

View file

@ -725,8 +725,7 @@ impl RegistryClient {
#[derive(
Default, Debug, Serialize, Deserialize, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize,
)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
pub struct VersionFiles {
pub wheels: Vec<VersionWheel>,
pub source_dists: Vec<VersionSourceDist>,
@ -757,16 +756,14 @@ impl VersionFiles {
}
#[derive(Debug, Serialize, Deserialize, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
pub struct VersionWheel {
pub name: WheelFilename,
pub file: File,
}
#[derive(Debug, Serialize, Deserialize, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
pub struct VersionSourceDist {
pub name: SourceDistFilename,
pub file: File,
@ -775,13 +772,11 @@ pub struct VersionSourceDist {
#[derive(
Default, Debug, Serialize, Deserialize, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize,
)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
pub struct SimpleMetadata(Vec<SimpleMetadatum>);
#[derive(Debug, Serialize, Deserialize, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
pub struct SimpleMetadatum {
pub version: Version,
pub files: VersionFiles,

View file

@ -7,39 +7,40 @@ Typical usage patterns with rkyv involve using an `&Archived<T>`, where values
of that type are cast from a `&[u8]`. The owned archive type in this module
effectively provides a way to use `Archive<T>` without needing to worry about
the lifetime of the buffer it's attached to. This works by making the owned
archive type own the buffer itself.
# Custom serializer
This module provides our own implementation of the `Serializer` trait.
This involves a fair bit of boiler plate, but it was largely copied from
`CompositeSerializer`. (Indeed, our serializer wraps a `CompositeSerializer`.)
The motivation for doing this is to support the archiving of `PathBuf` types.
Namely, for reasons AG doesn't completely understand at the time of writing,
the serializers that rkyv bundled cannot handle the error returned by `PathBuf`
potentially failing to serialize. Namely, since `PathBuf` has a platform
dependent representation when its contents are not valid UTF-8, serialization
in `rkyv` requires that it be valid UTF-8. If it isn't, serialization will
fail.
archive type own the buffer itself. It then provides convenient routines for
serializing and deserializing.
*/
use std::convert::Infallible;
use rkyv::{
de::deserializers::SharedDeserializeMap,
ser::serializers::{
AlignedSerializer, AllocScratch, AllocScratchError, CompositeSerializer,
CompositeSerializerError, FallbackScratch, HeapScratch, SharedSerializeMap,
SharedSerializeMapError,
},
api::high::{HighDeserializer, HighSerializer, HighValidator},
bytecheck::CheckBytes,
rancor,
ser::allocator::ArenaHandle,
util::AlignedVec,
validation::validators::DefaultValidator,
Archive, ArchiveUnsized, CheckBytes, Deserialize, Fallible, Serialize,
Archive, Deserialize, Portable, Serialize,
};
use crate::{Error, ErrorKind};
/// A convenient alias for the rkyv serializer used by `uv-client`.
///
/// This utilizes rkyv's `HighSerializer` but fixes its type parameters where
/// possible since we don't need the full flexibility of a generic serializer.
pub type Serializer<'a> = HighSerializer<AlignedVec, ArenaHandle<'a>, rancor::Error>;
/// A convenient alias for the rkyv deserializer used by `uv-client`.
///
/// This utilizes rkyv's `HighDeserializer` but fixes its type parameters
/// where possible since we don't need the full flexibility of a generic
/// deserializer.
pub type Deserializer = HighDeserializer<rancor::Error>;
/// A convenient alias for the rkyv validator used by `uv-client`.
///
/// This utilizes rkyv's `HighValidator` but fixes its type parameters where
/// possible since we don't need the full flexibility of a generic validator.
pub type Validator<'a> = HighValidator<'a, rancor::Error>;
/// An owned archived type.
///
/// This type is effectively an owned version of `Archived<A>`. Normally, when
@ -60,14 +61,14 @@ use crate::{Error, ErrorKind};
/// will likely need to be copied from here.
#[derive(Debug)]
pub struct OwnedArchive<A> {
raw: rkyv::util::AlignedVec,
raw: AlignedVec,
archive: std::marker::PhantomData<A>,
}
impl<A> OwnedArchive<A>
where
A: Archive + Serialize<Serializer<4096>>,
A::Archived: (for<'a> CheckBytes<DefaultValidator<'a>>) + Deserialize<A, SharedDeserializeMap>,
A: Archive + for<'a> Serialize<Serializer<'a>>,
A::Archived: Portable + Deserialize<A, Deserializer> + for<'a> CheckBytes<Validator<'a>>,
{
/// Create a new owned archived value from the raw aligned bytes of the
/// serialized representation of an `A`.
@ -80,7 +81,7 @@ where
// We convert the error to a simple string because... the error type
// does not implement Send. And I don't think we really need to keep
// the error type around anyway.
let _ = rkyv::validation::validators::check_archived_root::<A>(&raw)
let _ = rkyv::access::<A::Archived, rkyv::rancor::Error>(&raw)
.map_err(|e| ErrorKind::ArchiveRead(e.to_string()))?;
Ok(Self {
raw,
@ -110,13 +111,8 @@ where
/// Currently, this, at minimum, includes cases where an `A` contains a
/// `PathBuf` that is not valid UTF-8.
pub fn from_unarchived(unarchived: &A) -> Result<Self, Error> {
use rkyv::ser::Serializer;
let mut serializer = crate::rkyvutil::Serializer::<4096>::default();
serializer
.serialize_value(unarchived)
.map_err(ErrorKind::ArchiveWrite)?;
let raw = serializer.into_serializer().into_inner();
let raw = rkyv::to_bytes::<rancor::Error>(unarchived)
.map_err(|e| ErrorKind::ArchiveWrite(e.to_string()))?;
Ok(Self {
raw,
archive: std::marker::PhantomData,
@ -154,16 +150,14 @@ where
/// fully-qualified syntax. So, if `o` is an `OwnedValue`, then use
/// `OwnedValue::deserialize(&o)`.
pub fn deserialize(this: &Self) -> A {
(**this)
.deserialize(&mut SharedDeserializeMap::new())
.expect("valid archive must deserialize correctly")
rkyv::deserialize(&**this).expect("valid archive must deserialize correctly")
}
}
impl<A> std::ops::Deref for OwnedArchive<A>
where
A: Archive + Serialize<Serializer<4096>>,
A::Archived: (for<'a> CheckBytes<DefaultValidator<'a>>) + Deserialize<A, SharedDeserializeMap>,
A: Archive + for<'a> Serialize<Serializer<'a>>,
A::Archived: Portable + Deserialize<A, Deserializer> + for<'a> CheckBytes<Validator<'a>>,
{
type Target = A::Archived;
@ -174,175 +168,7 @@ where
// is guaranteed to be correct.
#[allow(unsafe_code)]
unsafe {
rkyv::archived_root::<A>(&self.raw)
rkyv::access_unchecked::<A::Archived>(&self.raw)
}
}
}
#[derive(Default)]
pub struct Serializer<const N: usize> {
composite: CompositeSerializer<
AlignedSerializer<AlignedVec>,
FallbackScratch<HeapScratch<N>, AllocScratch>,
SharedSerializeMap,
>,
}
impl<const N: usize> Serializer<N> {
fn into_serializer(self) -> AlignedSerializer<AlignedVec> {
self.composite.into_serializer()
}
}
impl<const N: usize> Fallible for Serializer<N> {
type Error = SerializerError;
}
impl<const N: usize> rkyv::ser::Serializer for Serializer<N> {
#[inline]
fn pos(&self) -> usize {
self.composite.pos()
}
#[inline]
fn write(&mut self, bytes: &[u8]) -> Result<(), Self::Error> {
self.composite
.write(bytes)
.map_err(SerializerError::Composite)
}
#[inline]
fn pad(&mut self, padding: usize) -> Result<(), Self::Error> {
self.composite
.pad(padding)
.map_err(SerializerError::Composite)
}
#[inline]
fn align(&mut self, align: usize) -> Result<usize, Self::Error> {
self.composite
.align(align)
.map_err(SerializerError::Composite)
}
#[inline]
fn align_for<T>(&mut self) -> Result<usize, Self::Error> {
self.composite
.align_for::<T>()
.map_err(SerializerError::Composite)
}
#[inline]
#[allow(unsafe_code)]
unsafe fn resolve_aligned<T: Archive + ?Sized>(
&mut self,
value: &T,
resolver: T::Resolver,
) -> Result<usize, Self::Error> {
self.composite
.resolve_aligned::<T>(value, resolver)
.map_err(SerializerError::Composite)
}
#[inline]
#[allow(unsafe_code)]
unsafe fn resolve_unsized_aligned<T: ArchiveUnsized + ?Sized>(
&mut self,
value: &T,
to: usize,
metadata_resolver: T::MetadataResolver,
) -> Result<usize, Self::Error> {
self.composite
.resolve_unsized_aligned(value, to, metadata_resolver)
.map_err(SerializerError::Composite)
}
}
impl<const N: usize> rkyv::ser::ScratchSpace for Serializer<N> {
#[inline]
#[allow(unsafe_code)]
unsafe fn push_scratch(
&mut self,
layout: std::alloc::Layout,
) -> Result<std::ptr::NonNull<[u8]>, Self::Error> {
self.composite
.push_scratch(layout)
.map_err(SerializerError::Composite)
}
#[inline]
#[allow(unsafe_code)]
unsafe fn pop_scratch(
&mut self,
ptr: std::ptr::NonNull<u8>,
layout: std::alloc::Layout,
) -> Result<(), Self::Error> {
self.composite
.pop_scratch(ptr, layout)
.map_err(SerializerError::Composite)
}
}
impl<const N: usize> rkyv::ser::SharedSerializeRegistry for Serializer<N> {
#[inline]
fn get_shared_ptr(&self, value: *const u8) -> Option<usize> {
self.composite.get_shared_ptr(value)
}
#[inline]
fn add_shared_ptr(&mut self, value: *const u8, pos: usize) -> Result<(), Self::Error> {
self.composite
.add_shared_ptr(value, pos)
.map_err(SerializerError::Composite)
}
}
#[derive(Debug)]
pub enum SerializerError {
Composite(CompositeSerializerError<Infallible, AllocScratchError, SharedSerializeMapError>),
AsString(rkyv::with::AsStringError),
}
impl std::fmt::Display for SerializerError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match *self {
Self::Composite(ref e) => e.fmt(f),
Self::AsString(ref e) => e.fmt(f),
}
}
}
impl std::error::Error for SerializerError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match *self {
Self::Composite(ref e) => Some(e),
Self::AsString(ref e) => Some(e),
}
}
}
/// Provides a way to build a serializer error if converting an
/// `OsString`/`PathBuf` to a `String` fails. i.e., It's invalid UTF-8.
///
/// This impl is the entire point of this module. For whatever reason, none of
/// the serializers in rkyv handle this particular error case. Apparently, the
/// only way to use `rkyv::with::AsString` with `PathBuf` is to create one's
/// own serializer and provide a `From` impl for the `AsStringError` type.
/// Specifically, from the [AsString] docs:
///
/// > Regular serializers dont support the custom error handling needed for
/// > this type by default. To use this wrapper, a custom serializer with an
/// > error type satisfying <S as Fallible>`::Error`: From<AsStringError> must be
/// > provided.
///
/// If we didn't need to use `rkyv::with::AsString` (which we do for
/// serializing `PathBuf` at time of writing), then we could just
/// use an `AllocSerializer` directly (which is a type alias for
/// `CompositeSerializer<...>`.
///
/// [AsString]: https://docs.rs/rkyv/0.7.43/rkyv/with/struct.AsString.html
impl From<rkyv::with::AsStringError> for SerializerError {
fn from(e: rkyv::with::AsStringError) -> Self {
Self::AsString(e)
}
}

View file

@ -26,8 +26,7 @@ use crate::{validate_and_normalize_owned, validate_and_normalize_ref, InvalidNam
rkyv::Serialize,
)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
pub struct PackageName(String);
impl PackageName {

View file

@ -1,5 +1,4 @@
use pubgrub::Range;
use rkyv::{de::deserializers::SharedDeserializeMap, Deserialize};
use std::collections::btree_map::{BTreeMap, Entry};
use std::sync::OnceLock;
use tracing::instrument;
@ -57,9 +56,7 @@ impl VersionMap {
// from a `VersionFiles` to a PrioritizedDist for each version
// isn't done until that specific version is requested.
for (datum_index, datum) in simple_metadata.iter().enumerate() {
let version: Version = datum
.version
.deserialize(&mut SharedDeserializeMap::new())
let version = rkyv::deserialize::<Version, rkyv::rancor::Error>(&datum.version)
.expect("archived version always deserializes");
stable |= version.is_stable();
map.insert(
@ -375,13 +372,14 @@ impl VersionMapLazy {
simple: &'p SimplePrioritizedDist,
) -> Option<&'p PrioritizedDist> {
let get_or_init = || {
let files: VersionFiles = self
.simple_metadata
.datum(simple.datum_index)
.expect("index to lazy dist is correct")
.files
.deserialize(&mut SharedDeserializeMap::new())
.expect("archived version files should deserialize");
let files = rkyv::deserialize::<VersionFiles, rkyv::rancor::Error>(
&self
.simple_metadata
.datum(simple.datum_index)
.expect("index to lazy dist is correct")
.files,
)
.expect("archived version files always deserializes");
let mut priority_dist = init.cloned().unwrap_or_default();
for (filename, file) in files.all() {
// Support resolving as if it were an earlier timestamp, at least as long files have

View file

@ -57,7 +57,7 @@ fn clean_package_pypi() -> Result<()> {
// Assert that the `.rkyv` file is created for `iniconfig`.
let rkyv = context
.cache_dir
.child("simple-v12")
.child("simple-v13")
.child("pypi")
.child("iniconfig.rkyv");
assert!(
@ -129,7 +129,7 @@ fn clean_package_index() -> Result<()> {
// Assert that the `.rkyv` file is created for `iniconfig`.
let rkyv = context
.cache_dir
.child("simple-v12")
.child("simple-v13")
.child("index")
.child("e8208120cae3ba69")
.child("iniconfig.rkyv");