Skip to content

Tune up project linting #1317

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
May 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
resolver = "1" # unifying Cargo features asap for Book tests
members = [
"benches",
"book",
"juniper_codegen",
"juniper",
"juniper_hyper",
Expand Down
13 changes: 11 additions & 2 deletions benches/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,23 @@ authors = ["Christoph Herzog <[email protected]>"]
publish = false

[dependencies]
dataloader = "0.18" # for Book only
futures = "0.3"
juniper = { path = "../juniper" }

[dev-dependencies]
criterion = "0.5"
tokio = { version = "1.0", features = ["rt-multi-thread"] }

[lints.clippy]
allow_attributes = "warn"
allow_attributes_without_reason = "warn"
[lints.rust]
closure_returning_async_block = "warn"
future_incompatible = { level = "warn", priority = -1 }
impl_trait_redundant_captures = "warn"
non_ascii_idents = "forbid"
unsafe_code = "forbid"
unused_crate_dependencies = "warn"

[[bench]]
name = "benchmark"
harness = false
6 changes: 6 additions & 0 deletions benches/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
#[cfg(test)]
mod for_benches_only {
use criterion as _;
use tokio as _;
}

use juniper::{
DefaultScalarValue, EmptyMutation, EmptySubscription, ExecutionError, FieldError, GraphQLEnum,
GraphQLObject, RootNode, Value, Variables, graphql_object,
Expand Down
20 changes: 20 additions & 0 deletions book/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[package]
name = "juniper_book"
version = "0.0.0"
edition = "2024"
authors = ["Kai Ren <[email protected]>"]
publish = false

[dependencies]
dataloader = "0.18" # for Book only

[lints.clippy]
allow_attributes = "warn"
allow_attributes_without_reason = "warn"
[lints.rust]
closure_returning_async_block = "warn"
future_incompatible = { level = "warn", priority = -1 }
impl_trait_redundant_captures = "warn"
non_ascii_idents = "forbid"
unsafe_code = "forbid"
unused_crate_dependencies = "warn"
3 changes: 3 additions & 0 deletions book/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
//! Crate keeping dependencies for running Book tests.

use dataloader as _;
2 changes: 1 addition & 1 deletion book/src/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Exposing simple enums and structs as [GraphQL] types is just a matter of adding
For more advanced mappings, [Juniper] provides multiple macros to map your [Rust] types to a [GraphQL schema][schema]. The most important one is the [`#[graphql_object]` attribute][2] that is used for declaring a [GraphQL object] with resolvers (typically used for declaring [`Query` and `Mutation` roots][1]).

```rust
# # ![allow(unused_variables)]
# #![expect(unused_variables, reason = "example")]
# extern crate juniper;
#
# use std::fmt::Display;
Expand Down
2 changes: 1 addition & 1 deletion book/src/types/enums.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ enum StarWarsEpisode {

By default, all [enum][3] variants are included in the generated [GraphQL enum][0] type as values. To prevent including a specific variant, annotate it with the `#[graphql(ignore)]` attribute:
```rust
# #![allow(dead_code)]
# #![expect(dead_code, reason = "example")]
# extern crate juniper;
# use juniper::GraphQLEnum;
#
Expand Down
2 changes: 1 addition & 1 deletion book/src/types/input_objects.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Input objects

In [Juniper], defining a [GraphQL input object][0] is quite straightforward and similar to how [trivial GraphQL objects are defined](objects/index.md) - by using the [`#[derive(GraphQLInputObject)]` attribute][2] on a [Rust struct][struct]:
```rust
# #![allow(unused_variables)]
# #![expect(unused_variables, reason = "example")]
# extern crate juniper;
# use juniper::{GraphQLInputObject, GraphQLObject, graphql_object};
#
Expand Down
2 changes: 1 addition & 1 deletion book/src/types/interfaces.md
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ trait Person {

By default, all [struct][24] fields or [trait][20] methods are considered as [GraphQL fields][4]. If a helper method is needed, or it should be ignored for some reason, then it should be marked with the `#[graphql(ignore)]` attribute:
```rust
# #![allow(dead_code)]
# #![expect(dead_code, reason = "example")]
# extern crate juniper;
# use std::marker::PhantomPinned;
# use juniper::{graphql_interface, GraphQLInterface};
Expand Down
2 changes: 1 addition & 1 deletion book/src/types/objects/complex_fields.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ impl Person {

By default, all methods of an [`impl` block][6] are exposed as [GraphQL fields][4]. If a method should not be exposed as a [GraphQL field][4], it should be defined in a separate [`impl` block][6] or marked with the `#[graphql(ignore)]` attribute:
```rust
# #![allow(dead_code)]
# #![expect(dead_code, reason = "example")]
# extern crate juniper;
# use juniper::graphql_object;
#
Expand Down
2 changes: 1 addition & 1 deletion book/src/types/objects/context.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ _Context_ is a feature in [Juniper] that lets [field][4] resolvers access global

Let's say that we have a simple `User`s database in a `HashMap`:
```rust
# #![allow(dead_code)]
# #![expect(dead_code, reason = "example")]
# use std::collections::HashMap;
#
struct Database {
Expand Down
2 changes: 1 addition & 1 deletion book/src/types/objects/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ struct Person {

By default, all [struct] fields are included into the generated [GraphQL object][0] type. To prevent inclusion of a specific field annotate it with the `#[graphql(ignore)]` attribute:
```rust
# #![allow(dead_code)]
# #![expect(dead_code, reason = "example")]
# extern crate juniper;
# use juniper::GraphQLObject;
#
Expand Down
15 changes: 12 additions & 3 deletions juniper/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,19 @@ serde_json = "1.0.18"
serial_test = "3.0"
tokio = { version = "1.0", features = ["macros", "time", "rt-multi-thread"] }

[lints.clippy]
allow_attributes = "warn"
allow_attributes_without_reason = "warn"
[lints.rust]
closure_returning_async_block = "warn"
future_incompatible = { level = "warn", priority = -1 }
impl_trait_redundant_captures = "warn"
missing_docs = "warn"
non_ascii_idents = "forbid"
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(nightly)'] }
unused_crate_dependencies = "warn"

[[bench]]
name = "bench"
harness = false
path = "benches/bench.rs"

[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(nightly)'] }
8 changes: 4 additions & 4 deletions juniper/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ pub enum Type<'a> {
/// Lists and objects variants are _spanned_, i.e. they contain a reference to
/// their position in the source file, if available.
#[derive(Clone, Debug, PartialEq)]
#[allow(missing_docs)]
#[expect(missing_docs, reason = "self-explanatory")]
pub enum InputValue<S = DefaultScalarValue> {
Null,
Scalar(S),
Expand Down Expand Up @@ -100,7 +100,7 @@ pub struct InlineFragment<'a, S> {
/// }
/// ```
#[derive(Clone, PartialEq, Debug)]
#[allow(missing_docs)]
#[expect(missing_docs, reason = "self-explanatory")]
pub enum Selection<'a, S = DefaultScalarValue> {
Field(Spanning<Field<'a, S>>),
FragmentSpread(Spanning<FragmentSpread<'a, S>>),
Expand All @@ -113,15 +113,15 @@ pub struct Directive<'a, S> {
pub arguments: Option<Spanning<Arguments<'a, S>>>,
}

#[allow(missing_docs)]
#[expect(missing_docs, reason = "self-explanatory")]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum OperationType {
Query,
Mutation,
Subscription,
}

#[allow(missing_docs)]
#[expect(missing_docs, reason = "self-explanatory")]
#[derive(Clone, PartialEq, Debug)]
pub struct Operation<'a, S> {
pub operation_type: OperationType,
Expand Down
2 changes: 1 addition & 1 deletion juniper/src/executor/look_ahead.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ type BorrowedSpanning<'a, T> = Spanning<T, &'a Span>;
/// variables get automatically resolved.
///
/// [0]: https://en.wikipedia.org/wiki/Look-ahead_(backtracking)
#[expect(missing_docs, reason = "self-explanatory")]
#[derive(Clone, Debug, PartialEq)]
#[allow(missing_docs)]
#[must_use]
pub enum LookAheadValue<'a, S: ScalarValue + 'a> {
Null,
Expand Down
4 changes: 1 addition & 3 deletions juniper/src/executor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ pub struct Registry<'r, S = DefaultScalarValue> {
pub types: FnvHashMap<Name, MetaType<'r, S>>,
}

#[allow(missing_docs)]
#[expect(missing_docs, reason = "self-explanatory")]
#[derive(Clone)]
pub enum FieldPath<'a> {
Root(SourcePosition),
Expand Down Expand Up @@ -349,7 +349,6 @@ where
{
type Type = T;

#[allow(clippy::type_complexity)]
fn into_resolvable(self, _: &'a C) -> FieldResult<Option<(&'a T::Context, Option<T>)>, S> {
Ok(self.map(|(ctx, v)| (ctx, Some(v))))
}
Expand Down Expand Up @@ -377,7 +376,6 @@ where
{
type Type = T;

#[allow(clippy::type_complexity)]
fn into_resolvable(self, _: &'a C) -> FieldResult<Option<(&'a T::Context, Option<T>)>, S2> {
self.map(|o| o.map(|(ctx, v)| (ctx, Some(v))))
.map_err(FieldError::map_scalar_value)
Expand Down
1 change: 0 additions & 1 deletion juniper/src/executor_tests/async_await/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ enum UserKind {
}

struct User {
#[allow(dead_code)]
id: i32,
name: String,
kind: UserKind,
Expand Down
3 changes: 2 additions & 1 deletion juniper/src/executor_tests/interfaces_unions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ mod interface {
types::scalars::{EmptyMutation, EmptySubscription},
};

#[allow(dead_code)] // TODO: Consider this for the GraphQL interfaces in the expansion.
// TODO: Consider this for the GraphQL interfaces in the expansion.
#[expect(dead_code, reason = "GraphQL schema testing")]
#[graphql_interface(for = [Cat, Dog])]
trait Pet {
fn name(&self) -> &str;
Expand Down
5 changes: 3 additions & 2 deletions juniper/src/executor_tests/introspection/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ mod enums;
mod input_object;

// This asserts that the input objects defined public actually became public
#[allow(unused_imports)]
#[expect(unused_imports, reason = "`pub` assertion")]
use self::input_object::{NamedPublic, NamedPublicWithDescription};

use crate::{
Expand All @@ -23,7 +23,8 @@ enum Sample {
struct Scalar(i32);

/// A sample interface
#[allow(dead_code)] // TODO: Consider this for the GraphQL interfaces in the expansion.
// TODO: Consider this for the GraphQL interfaces in the expansion.
#[expect(dead_code, reason = "GraphQL schema testing")]
#[graphql_interface(name = "SampleInterface", for = Root)]
trait Interface {
/// A sample field in the interface
Expand Down
20 changes: 16 additions & 4 deletions juniper/src/http/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -361,8 +361,9 @@ impl<S: ScalarValue> GraphQLBatchResponse<S> {
}

#[cfg(feature = "expose-test-schema")]
#[allow(missing_docs)]
pub mod tests {
//! HTTP integration tests.

use std::time::Duration;

use serde_json::Value as Json;
Expand All @@ -373,8 +374,13 @@ pub mod tests {
/// the http framework integration we are testing.
#[derive(Debug)]
pub struct TestResponse {
/// Status code of the HTTP response.
pub status_code: i32,

/// Body of the HTTP response, if any.
pub body: Option<String>,

/// `Content-Type` header value of the HTTP response.
pub content_type: String,
}

Expand All @@ -393,7 +399,7 @@ pub mod tests {
fn post_graphql(&self, url: &str, body: &str) -> TestResponse;
}

#[allow(missing_docs)]
/// Runs integration tests suite for the provided [`HttpIntegration`].
pub fn run_http_test_suite<T: HttpIntegration>(integration: &T) {
println!("Running HTTP Test suite for integration");

Expand Down Expand Up @@ -662,7 +668,10 @@ pub mod tests {

use super::{WS_INTEGRATION_EXPECT_DEFAULT_TIMEOUT, WsIntegration, WsIntegrationMessage};

#[allow(missing_docs)]
/// Runs integration tests suite for the [legacy `graphql-ws` GraphQL over WebSocket
/// Protocol][0].
///
/// [0]:https://github.com/apollographql/subscriptions-transport-ws/blob/v0.11.0/PROTOCOL.md
pub async fn run_test_suite<T: WsIntegration>(integration: &T) {
println!("Running `graphql-ws` test suite for integration");

Expand Down Expand Up @@ -791,7 +800,10 @@ pub mod tests {

use super::{WS_INTEGRATION_EXPECT_DEFAULT_TIMEOUT, WsIntegration, WsIntegrationMessage};

#[allow(missing_docs)]
/// Runs integration tests suite the [new `graphql-transport-ws` GraphQL over WebSocket
/// Protocol][new].
///
/// [new]: https://github.com/enisdenjo/graphql-ws/blob/v5.14.0/PROTOCOL.md
pub async fn run_test_suite<T: WsIntegration>(integration: &T) {
println!("Running `graphql-transport-ws` test suite for integration");

Expand Down
5 changes: 5 additions & 0 deletions juniper/src/integrations/bigdecimal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ use std::str::FromStr as _;

use crate::{InputValue, ScalarValue, Value, graphql_scalar};

// TODO: Try remove on upgrade of `bigdecimal` crate.
mod for_minimal_versions_check_only {
use num_bigint as _;
}

/// Big decimal type.
///
/// Allows storing any real number to arbitrary precision; which avoids common
Expand Down
5 changes: 5 additions & 0 deletions juniper/src/integrations/bson.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@

use crate::{InputValue, ScalarValue, Value, graphql_scalar};

// TODO: Try remove on upgrade of `bson` crate.
mod for_minimal_versions_check_only {
use tap as _;
}

/// [BSON ObjectId][0] represented as a HEX string.
///
/// [`ObjectID` scalar][1] compliant.
Expand Down
5 changes: 5 additions & 0 deletions juniper/src/integrations/chrono_tz.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@

use crate::{InputValue, ScalarValue, Value, graphql_scalar};

// TODO: Try remove on upgrade of `chrono-tz` crate.
mod for_minimal_versions_check_only {
use regex as _;
}

/// Timezone based on [`IANA` database][0].
///
/// See ["List of tz database time zones"][3] `TZ database name` column for
Expand Down
3 changes: 1 addition & 2 deletions juniper/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#![cfg_attr(not(any(doc, test)), doc = env!("CARGO_PKG_NAME"))]
// Due to `schema_introspection` test.
#![cfg_attr(test, recursion_limit = "256")]
#![warn(missing_docs)]

// Required for using `juniper_codegen` macros inside this crate to resolve
// absolute `::juniper` path correctly, without errors.
Expand Down Expand Up @@ -99,7 +98,7 @@ pub use crate::{
};

/// An error that prevented query execution
#[allow(missing_docs)]
#[expect(missing_docs, reason = "self-explanatory")]
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum GraphQLError {
ParseError(Spanning<ParseError>),
Expand Down
4 changes: 2 additions & 2 deletions juniper/src/parser/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub struct Lexer<'a> {
/// A single scalar value literal
///
/// This is only used for tagging how the lexer has interpreted a value literal
#[allow(missing_docs)]
#[expect(missing_docs, reason = "self-explanatory")]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum ScalarToken<'a> {
String(&'a str),
Expand All @@ -24,7 +24,7 @@ pub enum ScalarToken<'a> {
}

/// A single token in the input source
#[allow(missing_docs)]
#[expect(missing_docs, reason = "self-explanatory")]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Token<'a> {
Name(&'a str),
Expand Down
Loading