From 9afc8f1cf41226eb07c7ee764022bd0839c199cf Mon Sep 17 00:00:00 2001 From: Isabel Atkinson Date: Tue, 12 Nov 2024 14:53:20 -0700 Subject: [PATCH 1/3] migrate to derive-where --- Cargo.toml | 2 +- src/change_stream.rs | 7 +++---- src/client.rs | 10 ++++------ src/client/auth.rs | 8 ++++---- src/client/csfle.rs | 17 ++++------------- src/client/options.rs | 22 +++++++++++----------- src/client/session/cluster_time.rs | 8 ++++---- src/cmap.rs | 8 ++++---- src/cmap/conn.rs | 9 ++++----- src/cmap/options.rs | 8 ++++---- src/cursor.rs | 4 +++- src/cursor/common.rs | 7 +++---- src/event/cmap.rs | 17 ++++++++++------- src/selection_criteria.rs | 8 ++++---- 14 files changed, 63 insertions(+), 72 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3faf68adf..78f7fa08a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -76,8 +76,8 @@ chrono = { version = "0.4.7", default-features = false, features = [ "clock", "std", ] } -derivative = "2.1.1" derive_more = "0.99.17" +derive-where = "1.2.7" flate2 = { version = "1.0", optional = true } futures-io = "0.3.21" futures-core = "0.3.14" diff --git a/src/change_stream.rs b/src/change_stream.rs index 86c2bb0b7..928ece49c 100644 --- a/src/change_stream.rs +++ b/src/change_stream.rs @@ -14,7 +14,7 @@ use std::{ #[cfg(test)] use bson::RawDocumentBuf; use bson::{Document, Timestamp}; -use derivative::Derivative; +use derive_where::derive_where; use futures_core::{future::BoxFuture, Stream}; use serde::de::DeserializeOwned; #[cfg(test)] @@ -74,8 +74,7 @@ use crate::{ /// /// See the documentation [here](https://www.mongodb.com/docs/manual/changeStreams) for more /// details. Also see the documentation on [usage recommendations](https://www.mongodb.com/docs/manual/administration/change-streams-production-recommendations/). -#[derive(Derivative)] -#[derivative(Debug)] +#[derive_where(Debug)] pub struct ChangeStream where T: DeserializeOwned, @@ -90,7 +89,7 @@ where data: ChangeStreamData, /// A pending future for a resume. - #[derivative(Debug = "ignore")] + #[derive_where(skip)] pending_resume: Option>>>, } diff --git a/src/client.rs b/src/client.rs index 24f46e5b6..f99d6606c 100644 --- a/src/client.rs +++ b/src/client.rs @@ -16,7 +16,7 @@ use std::{ #[cfg(feature = "in-use-encryption")] pub use self::csfle::client_builder::*; -use derivative::Derivative; +use derive_where::derive_where; use futures_core::Future; use futures_util::FutureExt; @@ -124,8 +124,7 @@ const _: fn() = || { assert_sync(_c); }; -#[derive(Derivative)] -#[derivative(Debug)] +#[derive(Debug)] struct ClientInner { topology: Topology, options: ClientOptions, @@ -648,10 +647,9 @@ impl WeakClient { } } -#[derive(Derivative)] -#[derivative(Debug)] +#[derive_where(Debug)] pub(crate) struct AsyncDropToken { - #[derivative(Debug = "ignore")] + #[derive_where(skip)] tx: Option>>, } diff --git a/src/client/auth.rs b/src/client/auth.rs index fac3e6d16..30181a4f0 100644 --- a/src/client/auth.rs +++ b/src/client/auth.rs @@ -15,7 +15,7 @@ mod x509; use std::{borrow::Cow, fmt::Debug, str::FromStr}; use bson::RawDocumentBuf; -use derivative::Derivative; +use derive_where::derive_where; use hmac::{digest::KeyInit, Mac}; use rand::Rng; use serde::Deserialize; @@ -458,8 +458,8 @@ impl FromStr for AuthMechanism { /// /// Some fields (mechanism and source) may be omitted and will either be negotiated or assigned a /// default value, depending on the values of other fields in the credential. -#[derive(Clone, Default, Deserialize, TypedBuilder, Derivative)] -#[derivative(PartialEq)] +#[derive(Clone, Default, Deserialize, TypedBuilder)] +#[derive_where(PartialEq)] #[builder(field_defaults(default, setter(into)))] #[non_exhaustive] pub struct Credential { @@ -506,7 +506,7 @@ pub struct Credential { /// } /// ``` #[serde(skip)] - #[derivative(Debug = "ignore", PartialEq = "ignore")] + #[derive_where(skip)] #[builder(default)] pub oidc_callback: oidc::Callback, } diff --git a/src/client/csfle.rs b/src/client/csfle.rs index de45a6277..9e40e4dd4 100644 --- a/src/client/csfle.rs +++ b/src/client/csfle.rs @@ -5,7 +5,7 @@ pub(crate) mod state_machine; use std::{path::Path, time::Duration}; -use derivative::Derivative; +use derive_where::derive_where; use mongocrypt::Crypt; use crate::{ @@ -28,20 +28,17 @@ use self::state_machine::{CryptExecutor, MongocryptdOptions}; use super::WeakClient; -#[derive(Derivative)] -#[derivative(Debug)] +#[derive_where(Debug)] pub(super) struct ClientState { - #[derivative(Debug = "ignore")] + #[derive_where(skip)] crypt: Crypt, exec: CryptExecutor, - internal_client: Option, opts: AutoEncryptionOptions, } struct AuxClients { key_vault_client: WeakClient, metadata_client: Option, - internal_client: Option, } impl ClientState { @@ -76,12 +73,7 @@ impl ClientState { ) .await?; - Ok(Self { - crypt, - exec, - internal_client: aux_clients.internal_client, - opts, - }) + Ok(Self { crypt, exec, opts }) } pub(super) fn crypt(&self) -> &Crypt { @@ -197,7 +189,6 @@ impl ClientState { Ok(AuxClients { key_vault_client, metadata_client, - internal_client, }) } } diff --git a/src/client/options.rs b/src/client/options.rs index c58be4e4c..202b8e9c3 100644 --- a/src/client/options.rs +++ b/src/client/options.rs @@ -17,7 +17,7 @@ use std::{ }; use bson::UuidRepresentation; -use derivative::Derivative; +use derive_where::derive_where; use once_cell::sync::Lazy; use serde::{de::Unexpected, Deserialize, Deserializer, Serialize}; use serde_with::skip_serializing_none; @@ -349,9 +349,9 @@ pub struct ServerApi { } /// Contains the options that can be used to create a new [`Client`](../struct.Client.html). -#[derive(Clone, Derivative, Deserialize, TypedBuilder)] +#[derive(Clone, Deserialize, TypedBuilder)] #[builder(field_defaults(default, setter(into)))] -#[derivative(Debug, PartialEq)] +#[derive_where(Debug, PartialEq)] #[serde(rename_all = "camelCase")] #[non_exhaustive] pub struct ClientOptions { @@ -385,7 +385,7 @@ pub struct ClientOptions { pub compressors: Option>, /// The handler that should process all Connection Monitoring and Pooling events. - #[derivative(Debug = "ignore", PartialEq = "ignore")] + #[derive_where(skip)] #[builder(setter(strip_option))] #[serde(skip)] pub cmap_event_handler: Option>, @@ -393,7 +393,7 @@ pub struct ClientOptions { /// The handler that should process all command-related events. /// /// Note that monitoring command events may incur a performance penalty. - #[derivative(Debug = "ignore", PartialEq = "ignore")] + #[derive_where(skip)] #[builder(setter(strip_option))] #[serde(skip)] pub command_event_handler: Option>, @@ -489,7 +489,7 @@ pub struct ClientOptions { pub server_monitoring_mode: Option, /// The handler that should process all Server Discovery and Monitoring events. - #[derivative(Debug = "ignore", PartialEq = "ignore")] + #[derive_where(skip)] #[builder(setter(strip_option))] #[serde(skip)] pub sdam_event_handler: Option>, @@ -526,7 +526,7 @@ pub struct ClientOptions { pub srv_service_name: Option, #[builder(setter(skip))] - #[derivative(Debug = "ignore")] + #[derive_where(skip(Debug))] pub(crate) socket_timeout: Option, /// The TLS configuration for the Client to use in its connections with the server. @@ -556,12 +556,12 @@ pub struct ClientOptions { /// Information from the SRV URI that generated these client options, if applicable. #[builder(setter(skip))] #[serde(skip)] - #[derivative(Debug = "ignore")] + #[derive_where(skip(Debug))] pub(crate) original_srv_info: Option, #[cfg(test)] #[builder(setter(skip))] - #[derivative(Debug = "ignore")] + #[derive_where(skip(Debug))] pub(crate) original_uri: Option, /// Configuration of the DNS resolver used for SRV and TXT lookups. @@ -571,7 +571,7 @@ pub struct ClientOptions { /// system configuration, so a custom configuration is recommended. #[builder(setter(skip))] #[serde(skip)] - #[derivative(Debug = "ignore")] + #[derive_where(skip(Debug))] #[cfg(feature = "dns-resolver")] pub(crate) resolver_config: Option, @@ -579,7 +579,7 @@ pub struct ClientOptions { #[cfg(test)] #[builder(setter(skip))] #[serde(skip)] - #[derivative(PartialEq = "ignore")] + #[derive_where(skip)] pub(crate) test_options: Option, } diff --git a/src/client/session/cluster_time.rs b/src/client/session/cluster_time.rs index 33699be15..30bf5ea03 100644 --- a/src/client/session/cluster_time.rs +++ b/src/client/session/cluster_time.rs @@ -1,4 +1,4 @@ -use derivative::Derivative; +use derive_where::derive_where; use serde::{Deserialize, Serialize}; use crate::bson::{Document, Timestamp}; @@ -7,13 +7,13 @@ use crate::bson::{Document, Timestamp}; /// /// See [the MongoDB documentation](https://www.mongodb.com/docs/manual/core/read-isolation-consistency-recency/) /// for more information. -#[derive(Debug, Deserialize, Clone, Serialize, Derivative)] -#[derivative(PartialEq, Eq)] +#[derive(Debug, Deserialize, Clone, Serialize)] +#[derive_where(PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct ClusterTime { pub(crate) cluster_time: Timestamp, - #[derivative(PartialEq = "ignore")] + #[derive_where(skip)] pub(crate) signature: Document, } diff --git a/src/cmap.rs b/src/cmap.rs index 4d8e6c9e3..ca0f6445d 100644 --- a/src/cmap.rs +++ b/src/cmap.rs @@ -11,7 +11,7 @@ mod worker; use std::time::Instant; -use derivative::Derivative; +use derive_where::derive_where; pub use self::conn::ConnectionInfo; pub(crate) use self::{ @@ -51,15 +51,15 @@ pub(crate) const DEFAULT_MAX_POOL_SIZE: u32 = 10; /// A pool of connections implementing the CMAP spec. /// This type is actually a handle to task that manages the connections and is cheap to clone and /// pass around. -#[derive(Clone, Derivative)] -#[derivative(Debug)] +#[derive(Clone)] +#[derive_where(Debug)] pub(crate) struct ConnectionPool { address: ServerAddress, manager: PoolManager, connection_requester: ConnectionRequester, generation_subscriber: PoolGenerationSubscriber, - #[derivative(Debug = "ignore")] + #[derive_where(skip)] event_emitter: CmapEventEmitter, } diff --git a/src/cmap/conn.rs b/src/cmap/conn.rs index c5b48c1c8..79fbc9483 100644 --- a/src/cmap/conn.rs +++ b/src/cmap/conn.rs @@ -7,7 +7,7 @@ use std::{ time::{Duration, Instant}, }; -use derivative::Derivative; +use derive_where::derive_where; use serde::Serialize; use tokio::{ io::BufStream, @@ -59,8 +59,7 @@ pub struct ConnectionInfo { } /// A wrapper around Stream that contains all the CMAP information needed to maintain a connection. -#[derive(Derivative)] -#[derivative(Debug)] +#[derive_where(Debug)] pub(crate) struct Connection { /// Driver-generated ID for the connection. pub(crate) id: u32, @@ -118,11 +117,11 @@ pub(crate) struct Connection { /// Type responsible for emitting events related to this connection. This is None for /// monitoring connections as we do not emit events for those. - #[derivative(Debug = "ignore")] + #[derive_where(skip)] event_emitter: Option, /// The token callback for OIDC authentication. - #[derivative(Debug = "ignore")] + #[derive_where(skip)] pub(crate) oidc_token_gen_id: tokio::sync::Mutex, } diff --git a/src/cmap/options.rs b/src/cmap/options.rs index ae760d89d..66b171dca 100644 --- a/src/cmap/options.rs +++ b/src/cmap/options.rs @@ -2,7 +2,7 @@ use std::cmp::Ordering; use std::time::Duration; -use derivative::Derivative; +use derive_where::derive_where; #[cfg(test)] use serde::de::{Deserializer, Error}; use serde::Deserialize; @@ -18,8 +18,8 @@ use crate::{ }; /// Contains the options for creating a connection pool. -#[derive(Clone, Default, Deserialize, Derivative)] -#[derivative(Debug, PartialEq)] +#[derive(Clone, Default, Deserialize)] +#[derive_where(Debug, PartialEq)] #[serde(rename_all = "camelCase")] pub(crate) struct ConnectionPoolOptions { /// The credential to use for authenticating connections in this pool. @@ -27,7 +27,7 @@ pub(crate) struct ConnectionPoolOptions { pub(crate) credential: Option, /// Processes all events generated by the pool. - #[derivative(Debug = "ignore", PartialEq = "ignore")] + #[derive_where(skip)] #[serde(skip)] pub(crate) cmap_event_handler: Option>, diff --git a/src/cursor.rs b/src/cursor.rs index d22474441..b40a8b56b 100644 --- a/src/cursor.rs +++ b/src/cursor.rs @@ -12,6 +12,7 @@ use bson::RawDocument; #[cfg(test)] use bson::RawDocumentBuf; +use derive_where::derive_where; use futures_core::Stream; use serde::{de::DeserializeOwned, Deserialize}; #[cfg(test)] @@ -98,7 +99,7 @@ pub(crate) use common::{ /// If a [`Cursor`] is still open when it goes out of scope, it will automatically be closed via an /// asynchronous [killCursors](https://www.mongodb.com/docs/manual/reference/command/killCursors/) command executed /// from its [`Drop`](https://doc.rust-lang.org/std/ops/trait.Drop.html) implementation. -#[derive(Debug)] +#[derive_where(Debug)] pub struct Cursor { client: Client, drop_token: AsyncDropToken, @@ -108,6 +109,7 @@ pub struct Cursor { drop_address: Option, #[cfg(test)] kill_watcher: Option>, + #[derive_where(skip)] _phantom: std::marker::PhantomData T>, } diff --git a/src/cursor/common.rs b/src/cursor/common.rs index 4c8bc3b5a..6fc891f83 100644 --- a/src/cursor/common.rs +++ b/src/cursor/common.rs @@ -6,7 +6,7 @@ use std::{ }; use bson::{RawDocument, RawDocumentBuf}; -use derivative::Derivative; +use derive_where::derive_where; use futures_core::{future::BoxFuture, Future}; #[cfg(test)] use tokio::sync::oneshot; @@ -35,10 +35,9 @@ pub(super) enum AdvanceResult { } /// An internal cursor that can be used in a variety of contexts depending on its `GetMoreProvider`. -#[derive(Derivative)] -#[derivative(Debug)] +#[derive_where(Debug)] pub(super) struct GenericCursor<'s, S> { - #[derivative(Debug = "ignore")] + #[derive_where(skip)] provider: GetMoreProvider<'s, S>, client: Client, info: CursorInformation, diff --git a/src/event/cmap.rs b/src/event/cmap.rs index bf0c4a453..1b90d2a9f 100644 --- a/src/event/cmap.rs +++ b/src/event/cmap.rs @@ -6,8 +6,9 @@ use std::time::Duration; use serde::{Deserialize, Serialize}; use crate::{bson::oid::ObjectId, options::ServerAddress, serde_util}; -use derivative::Derivative; use derive_more::From; +#[cfg(feature = "tracing-unstable")] +use derive_where::derive_where; #[cfg(feature = "tracing-unstable")] use crate::trace::{ @@ -144,8 +145,9 @@ pub struct ConnectionReadyEvent { } /// Event emitted when a connection is closed. -#[derive(Clone, Debug, Deserialize, Derivative, Serialize)] -#[derivative(PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize)] +#[cfg_attr(feature = "tracing-unstable", derive_where(PartialEq))] +#[cfg_attr(not(feature = "tracing-unstable"), derive(PartialEq))] #[serde(rename_all = "camelCase")] #[non_exhaustive] pub struct ConnectionClosedEvent { @@ -167,7 +169,7 @@ pub struct ConnectionClosedEvent { /// in future work we may add this to public API on the event itself. TODO: DRIVERS-2495 #[cfg(feature = "tracing-unstable")] #[serde(skip)] - #[derivative(PartialEq = "ignore")] + #[derive_where(skip)] pub(crate) error: Option, } @@ -203,8 +205,9 @@ pub struct ConnectionCheckoutStartedEvent { } /// Event emitted when a thread is unable to check out a connection. -#[derive(Clone, Debug, Deserialize, Derivative, Serialize)] -#[derivative(PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize)] +#[cfg_attr(feature = "tracing-unstable", derive_where(PartialEq))] +#[cfg_attr(not(feature = "tracing-unstable"), derive(PartialEq))] #[non_exhaustive] pub struct ConnectionCheckoutFailedEvent { /// The address of the server that the connection would have connected to. @@ -220,7 +223,7 @@ pub struct ConnectionCheckoutFailedEvent { /// in future work we may add this to public API on the event itself. TODO: DRIVERS-2495 #[cfg(feature = "tracing-unstable")] #[serde(skip)] - #[derivative(PartialEq = "ignore")] + #[derive_where(skip)] pub(crate) error: Option, /// See [ConnectionCheckedOutEvent::duration]. diff --git a/src/selection_criteria.rs b/src/selection_criteria.rs index 968c89a31..4fce8125c 100644 --- a/src/selection_criteria.rs +++ b/src/selection_criteria.rs @@ -1,6 +1,6 @@ use std::{collections::HashMap, sync::Arc, time::Duration}; -use derivative::Derivative; +use derive_where::derive_where; use serde::{de::Error as SerdeError, Deserialize, Deserializer, Serialize}; use typed_builder::TypedBuilder; @@ -13,8 +13,8 @@ use crate::{ }; /// Describes which servers are suitable for a given operation. -#[derive(Clone, Derivative, derive_more::Display)] -#[derivative(Debug)] +#[derive(Clone, derive_more::Display)] +#[derive_where(Debug)] #[non_exhaustive] pub enum SelectionCriteria { /// A read preference that describes the suitable servers based on the server type, max @@ -27,7 +27,7 @@ pub enum SelectionCriteria { /// A predicate used to filter servers that are considered suitable. A `server` will be /// considered suitable by a `predicate` if `predicate(server)` returns true. #[display(fmt = "Custom predicate")] - Predicate(#[derivative(Debug = "ignore")] Predicate), + Predicate(#[derive_where(skip)] Predicate), } impl PartialEq for SelectionCriteria { From c0590cda5c408de31cab3bdc5eb48b5dbdbb6186 Mon Sep 17 00:00:00 2001 From: Isabel Atkinson Date: Wed, 13 Nov 2024 08:39:56 -0700 Subject: [PATCH 2/3] suppress lint --- src/client/csfle.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/client/csfle.rs b/src/client/csfle.rs index 9e40e4dd4..45d030f82 100644 --- a/src/client/csfle.rs +++ b/src/client/csfle.rs @@ -33,12 +33,15 @@ pub(super) struct ClientState { #[derive_where(skip)] crypt: Crypt, exec: CryptExecutor, + #[allow(dead_code)] + internal_client: Option, opts: AutoEncryptionOptions, } struct AuxClients { key_vault_client: WeakClient, metadata_client: Option, + internal_client: Option, } impl ClientState { @@ -73,7 +76,12 @@ impl ClientState { ) .await?; - Ok(Self { crypt, exec, opts }) + Ok(Self { + crypt, + exec, + internal_client: aux_clients.internal_client, + opts, + }) } pub(super) fn crypt(&self) -> &Crypt { @@ -189,6 +197,7 @@ impl ClientState { Ok(AuxClients { key_vault_client, metadata_client, + internal_client, }) } } From 3117b511efc11fd422e706d373ca039562516998 Mon Sep 17 00:00:00 2001 From: Isabel Atkinson Date: Wed, 13 Nov 2024 08:40:36 -0700 Subject: [PATCH 3/3] rename --- src/client/csfle.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/client/csfle.rs b/src/client/csfle.rs index 45d030f82..0f270cf9b 100644 --- a/src/client/csfle.rs +++ b/src/client/csfle.rs @@ -33,8 +33,7 @@ pub(super) struct ClientState { #[derive_where(skip)] crypt: Crypt, exec: CryptExecutor, - #[allow(dead_code)] - internal_client: Option, + _internal_client: Option, opts: AutoEncryptionOptions, } @@ -79,7 +78,7 @@ impl ClientState { Ok(Self { crypt, exec, - internal_client: aux_clients.internal_client, + _internal_client: aux_clients.internal_client, opts, }) }