From 538b0f1099d030cbfd3917b0b43138a28350298d Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Tue, 24 Sep 2024 13:23:47 -0400 Subject: [PATCH] Remove `serde::Serialize` implementations for rkyv-able structs (#7663) ## Summary Random, but I noticed that we can remove a ton of serialize and deserialize derives by using `rkyv` for the flat-index caches. (We already use `rkyv` for these same structs in the registry cache.) --- crates/distribution-types/src/file.rs | 8 ++------ crates/pypi-types/src/simple_json.rs | 1 - crates/uv-cache/src/lib.rs | 2 +- crates/uv-client/src/flat_index.rs | 14 +++++++++----- crates/uv-client/src/registry_client.rs | 15 +++++---------- crates/uv-normalize/src/group_name.rs | 4 ++-- crates/uv-workspace/src/pyproject.rs | 19 ++++++++++++------- 7 files changed, 31 insertions(+), 32 deletions(-) diff --git a/crates/distribution-types/src/file.rs b/crates/distribution-types/src/file.rs index 2873e823b656..078f65f6aa07 100644 --- a/crates/distribution-types/src/file.rs +++ b/crates/distribution-types/src/file.rs @@ -21,9 +21,7 @@ pub enum FileConversionError { } /// Internal analog to [`pypi_types::File`]. -#[derive( - Debug, Clone, Hash, Serialize, Deserialize, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize, -)] +#[derive(Debug, Clone, Hash, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)] #[rkyv(derive(Debug))] pub struct File { pub dist_info_metadata: bool, @@ -68,9 +66,7 @@ impl File { } /// While a registry file is generally a remote URL, it can also be a file if it comes from a directory flat indexes. -#[derive( - Debug, Clone, Hash, Serialize, Deserialize, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize, -)] +#[derive(Debug, Clone, Hash, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)] #[rkyv(derive(Debug))] pub enum FileLocation { /// URL relative to the base URL. diff --git a/crates/pypi-types/src/simple_json.rs b/crates/pypi-types/src/simple_json.rs index 443e0f3e4280..d32f1ac64ad4 100644 --- a/crates/pypi-types/src/simple_json.rs +++ b/crates/pypi-types/src/simple_json.rs @@ -93,7 +93,6 @@ impl CoreMetadata { PartialEq, Eq, Hash, - Serialize, Deserialize, rkyv::Archive, rkyv::Deserialize, diff --git a/crates/uv-cache/src/lib.rs b/crates/uv-cache/src/lib.rs index 2e0719cc62f5..73b1958f8422 100644 --- a/crates/uv-cache/src/lib.rs +++ b/crates/uv-cache/src/lib.rs @@ -765,7 +765,7 @@ impl CacheBucket { fn to_str(self) -> &'static str { match self { Self::SourceDistributions => "sdists-v4", - Self::FlatIndex => "flat-index-v0", + Self::FlatIndex => "flat-index-v1", Self::Git => "git-v0", Self::Interpreter => "interpreter-v2", // Note that when bumping this, you'll also need to bump it diff --git a/crates/uv-client/src/flat_index.rs b/crates/uv-client/src/flat_index.rs index 94deec2bd43c..04e1c5243186 100644 --- a/crates/uv-client/src/flat_index.rs +++ b/crates/uv-client/src/flat_index.rs @@ -11,7 +11,7 @@ use uv_cache::{Cache, CacheBucket}; use crate::cached_client::{CacheControl, CachedClientError}; use crate::html::SimpleHtml; -use crate::{Connectivity, Error, ErrorKind, RegistryClient}; +use crate::{Connectivity, Error, ErrorKind, OwnedArchive, RegistryClient}; #[derive(Debug, thiserror::Error)] pub enum FlatIndexError { @@ -170,7 +170,7 @@ impl<'a> FlatIndexClient<'a> { let SimpleHtml { base, files } = SimpleHtml::parse(&text, &url) .map_err(|err| Error::from_html_err(err, url.clone()))?; - let files: Vec = files + let unarchived: Vec = files .into_iter() .filter_map(|file| { match File::try_from(file, base.as_url()) { @@ -183,7 +183,7 @@ impl<'a> FlatIndexClient<'a> { } }) .collect(); - Ok::, CachedClientError>(files) + OwnedArchive::from_unarchived(&unarchived) } .boxed_local() .instrument(info_span!("parse_flat_index_html", url = % url)) @@ -191,7 +191,7 @@ impl<'a> FlatIndexClient<'a> { let response = self .client .cached_client() - .get_serde( + .get_cacheable( flat_index_request, &cache_entry, cache_control, @@ -201,7 +201,11 @@ impl<'a> FlatIndexClient<'a> { match response { Ok(files) => { let files = files - .into_iter() + .iter() + .map(|file| { + rkyv::deserialize::(file) + .expect("archived version always deserializes") + }) .filter_map(|file| { Some(( DistFilename::try_from_normalized_filename(&file.filename)?, diff --git a/crates/uv-client/src/registry_client.rs b/crates/uv-client/src/registry_client.rs index e4d51cd5ceb9..392e17647cf5 100644 --- a/crates/uv-client/src/registry_client.rs +++ b/crates/uv-client/src/registry_client.rs @@ -8,7 +8,6 @@ use futures::{FutureExt, TryStreamExt}; use http::HeaderMap; use reqwest::{Client, Response, StatusCode}; use reqwest_middleware::ClientWithMiddleware; -use serde::{Deserialize, Serialize}; use tracing::{info_span, instrument, trace, warn, Instrument}; use url::Url; @@ -723,9 +722,7 @@ impl RegistryClient { } } -#[derive( - Default, Debug, Serialize, Deserialize, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize, -)] +#[derive(Default, Debug, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)] #[rkyv(derive(Debug))] pub struct VersionFiles { pub wheels: Vec, @@ -756,27 +753,25 @@ impl VersionFiles { } } -#[derive(Debug, Serialize, Deserialize, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)] +#[derive(Debug, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)] #[rkyv(derive(Debug))] pub struct VersionWheel { pub name: WheelFilename, pub file: File, } -#[derive(Debug, Serialize, Deserialize, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)] +#[derive(Debug, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)] #[rkyv(derive(Debug))] pub struct VersionSourceDist { pub name: SourceDistFilename, pub file: File, } -#[derive( - Default, Debug, Serialize, Deserialize, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize, -)] +#[derive(Default, Debug, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)] #[rkyv(derive(Debug))] pub struct SimpleMetadata(Vec); -#[derive(Debug, Serialize, Deserialize, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)] +#[derive(Debug, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)] #[rkyv(derive(Debug))] pub struct SimpleMetadatum { pub version: Version, diff --git a/crates/uv-normalize/src/group_name.rs b/crates/uv-normalize/src/group_name.rs index 87588ac9f28f..d41d3791cb45 100644 --- a/crates/uv-normalize/src/group_name.rs +++ b/crates/uv-normalize/src/group_name.rs @@ -3,7 +3,7 @@ use std::fmt::{Display, Formatter}; use std::str::FromStr; use std::sync::LazyLock; -use serde::{Deserialize, Deserializer, Serialize}; +use serde::{Deserialize, Deserializer}; use crate::{validate_and_normalize_owned, validate_and_normalize_ref, InvalidNameError}; @@ -12,7 +12,7 @@ use crate::{validate_and_normalize_owned, validate_and_normalize_ref, InvalidNam /// See: /// - /// - -#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize)] +#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct GroupName(String); diff --git a/crates/uv-workspace/src/pyproject.rs b/crates/uv-workspace/src/pyproject.rs index 4553468cb21c..4a212e21b095 100644 --- a/crates/uv-workspace/src/pyproject.rs +++ b/crates/uv-workspace/src/pyproject.rs @@ -33,7 +33,8 @@ pub enum PyprojectTomlError { } /// A `pyproject.toml` as specified in PEP 517. -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Deserialize, Debug, Clone)] +#[cfg_attr(test, derive(Serialize))] #[serde(rename_all = "kebab-case")] pub struct PyProjectToml { /// PEP 621-compliant project metadata. @@ -111,7 +112,8 @@ impl AsRef<[u8]> for PyProjectToml { /// PEP 621 project metadata (`project`). /// /// See . -#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] +#[derive(Deserialize, Debug, Clone, PartialEq)] +#[cfg_attr(test, derive(Serialize))] #[serde(rename_all = "kebab-case")] pub struct Project { /// The name of the project @@ -133,7 +135,8 @@ pub struct Project { pub(crate) scripts: Option, } -#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] +#[derive(Deserialize, Debug, Clone, PartialEq, Eq)] +#[cfg_attr(test, derive(Serialize))] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct Tool { pub uv: Option, @@ -141,7 +144,8 @@ pub struct Tool { // NOTE(charlie): When adding fields to this struct, mark them as ignored on `Options` in // `crates/uv-settings/src/settings.rs`. -#[derive(Serialize, Deserialize, OptionsMetadata, Debug, Clone, PartialEq, Eq)] +#[derive(Deserialize, OptionsMetadata, Debug, Clone, PartialEq, Eq)] +#[cfg_attr(test, derive(Serialize))] #[serde(rename_all = "kebab-case")] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct ToolUv { @@ -287,9 +291,9 @@ pub struct ToolUv { pub constraint_dependencies: Option>>, } -#[derive(Serialize, Default, Debug, Clone, PartialEq, Eq)] +#[derive(Default, Debug, Clone, PartialEq, Eq)] +#[cfg_attr(test, derive(Serialize))] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] -#[serde(rename_all = "kebab-case", deny_unknown_fields)] pub struct ToolUvSources(BTreeMap); impl ToolUvSources { @@ -346,7 +350,8 @@ impl<'de> serde::de::Deserialize<'de> for ToolUvSources { } } -#[derive(Serialize, Deserialize, OptionsMetadata, Default, Debug, Clone, PartialEq, Eq)] +#[derive(Deserialize, OptionsMetadata, Default, Debug, Clone, PartialEq, Eq)] +#[cfg_attr(test, derive(Serialize))] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[serde(rename_all = "kebab-case", deny_unknown_fields)] pub struct ToolUvWorkspace {