Add `Schema::build_with_ignore_name_conflicts` method to specifies a list to ignore type conflict detection.
This commit is contained in:
parent
e09494ae03
commit
d0bb37f419
|
@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
# [4.0.1] 2022-5-24
|
||||
|
||||
- Add `Schema::build_with_ignore_name_conflicts` method to specifies a list to ignore type conflict detection.
|
||||
|
||||
# [4.0.0] 2022-5-17
|
||||
|
||||
- Implement the `ConnectionNameType` and `EdgeNameType` traits to specify GraphQL type names for `Connection` and `Edge`, which can be automatically generated using `DefaultConnectionName` and `DefaultEdgeName`.
|
||||
|
|
|
@ -403,6 +403,7 @@ pub struct Registry {
|
|||
pub introspection_mode: IntrospectionMode,
|
||||
pub enable_federation: bool,
|
||||
pub federation_subscription: bool,
|
||||
pub ignore_name_conflicts: HashSet<String>,
|
||||
}
|
||||
|
||||
impl Registry {
|
||||
|
@ -462,7 +463,8 @@ impl Registry {
|
|||
return;
|
||||
}
|
||||
|
||||
if rust_typename != prev_typename {
|
||||
if rust_typename != prev_typename && !self.ignore_name_conflicts.contains(name)
|
||||
{
|
||||
panic!(
|
||||
"`{}` and `{}` have the same GraphQL name `{}`",
|
||||
prev_typename, rust_typename, name,
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
use std::{any::Any, collections::HashMap, ops::Deref, sync::Arc};
|
||||
use std::{
|
||||
any::Any,
|
||||
collections::{HashMap, HashSet},
|
||||
ops::Deref,
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use futures_util::stream::{self, Stream, StreamExt};
|
||||
use indexmap::map::IndexMap;
|
||||
|
@ -302,12 +307,32 @@ where
|
|||
mutation: Mutation,
|
||||
subscription: Subscription,
|
||||
) -> SchemaBuilder<Query, Mutation, Subscription> {
|
||||
Self::build_with_ignore_name_conflicts(query, mutation, subscription, [] as [&str; 0])
|
||||
}
|
||||
|
||||
/// Create a schema builder and specifies a list to ignore type conflict
|
||||
/// detection.
|
||||
///
|
||||
/// NOTE: It is not recommended to use it unless you know what it does.
|
||||
#[must_use]
|
||||
pub fn build_with_ignore_name_conflicts<I, T>(
|
||||
query: Query,
|
||||
mutation: Mutation,
|
||||
subscription: Subscription,
|
||||
ignore_name_conflicts: I,
|
||||
) -> SchemaBuilder<Query, Mutation, Subscription>
|
||||
where
|
||||
I: IntoIterator<Item = T>,
|
||||
T: Into<String>,
|
||||
{
|
||||
SchemaBuilder {
|
||||
validation_mode: ValidationMode::Strict,
|
||||
query: QueryRoot { inner: query },
|
||||
mutation,
|
||||
subscription,
|
||||
registry: Self::create_registry(),
|
||||
registry: Self::create_registry(
|
||||
ignore_name_conflicts.into_iter().map(Into::into).collect(),
|
||||
),
|
||||
data: Default::default(),
|
||||
complexity: None,
|
||||
depth: None,
|
||||
|
@ -316,7 +341,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn create_registry() -> Registry {
|
||||
pub(crate) fn create_registry(ignore_name_conflicts: HashSet<String>) -> Registry {
|
||||
let mut registry = Registry {
|
||||
types: Default::default(),
|
||||
directives: Default::default(),
|
||||
|
@ -335,6 +360,7 @@ where
|
|||
introspection_mode: IntrospectionMode::Enabled,
|
||||
enable_federation: false,
|
||||
federation_subscription: false,
|
||||
ignore_name_conflicts,
|
||||
};
|
||||
|
||||
registry.add_directive(MetaDirective {
|
||||
|
|
|
@ -171,7 +171,8 @@ mod tests {
|
|||
}
|
||||
|
||||
fn check_complex(query: &str, expect_complex: usize) {
|
||||
let registry = Schema::<Query, EmptyMutation, Subscription>::create_registry();
|
||||
let registry =
|
||||
Schema::<Query, EmptyMutation, Subscription>::create_registry(Default::default());
|
||||
let doc = parse_query(query).unwrap();
|
||||
let mut ctx = VisitorContext::new(®istry, &doc, None);
|
||||
let mut complex = 0;
|
||||
|
|
|
@ -76,7 +76,8 @@ mod tests {
|
|||
}
|
||||
|
||||
fn check_depth(query: &str, expect_depth: usize) {
|
||||
let registry = Schema::<Query, EmptyMutation, EmptySubscription>::create_registry();
|
||||
let registry =
|
||||
Schema::<Query, EmptyMutation, EmptySubscription>::create_registry(Default::default());
|
||||
let doc = parse_query(query).unwrap();
|
||||
let mut ctx = VisitorContext::new(®istry, &doc, None);
|
||||
let mut depth = 0;
|
||||
|
|
|
@ -141,3 +141,55 @@ async fn test_object_process_with_field() {
|
|||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn ignore_name_conflicts() {
|
||||
#[derive(SimpleObject)]
|
||||
#[graphql(name = "MyObj")]
|
||||
struct MyObj {
|
||||
name: String,
|
||||
}
|
||||
|
||||
#[derive(SimpleObject)]
|
||||
#[graphql(name = "MyObj")]
|
||||
struct MyObjRef<'a> {
|
||||
name: &'a str,
|
||||
}
|
||||
|
||||
struct Query;
|
||||
|
||||
#[Object]
|
||||
impl Query {
|
||||
async fn obj_owned(&self) -> MyObj {
|
||||
MyObj {
|
||||
name: "a".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
async fn obj_ref(&self) -> MyObjRef<'_> {
|
||||
MyObjRef { name: "b" }
|
||||
}
|
||||
}
|
||||
|
||||
let schema = Schema::build_with_ignore_name_conflicts(
|
||||
Query,
|
||||
EmptyMutation,
|
||||
EmptySubscription,
|
||||
["MyObj"],
|
||||
)
|
||||
.finish();
|
||||
|
||||
let query = r#"
|
||||
{
|
||||
objOwned { name }
|
||||
objRef { name }
|
||||
}
|
||||
"#;
|
||||
assert_eq!(
|
||||
schema.execute(query).await.into_result().unwrap().data,
|
||||
value!({
|
||||
"objOwned": { "name": "a" },
|
||||
"objRef": { "name": "b" },
|
||||
})
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue