Skip to content

Commit 5f8c172

Browse files
authored
codegen: fix required ID deserialization (#523)
Fixes #522
1 parent 8fb528a commit 5f8c172

File tree

2 files changed

+33
-17
lines changed

2 files changed

+33
-17
lines changed

graphql_client/src/serde_with.rs

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,22 @@
22
33
use serde::{Deserialize, Deserializer};
44

5+
#[derive(Deserialize)]
6+
#[serde(untagged)]
7+
enum IntOrString {
8+
Int(i64),
9+
Str(String),
10+
}
11+
12+
impl From<IntOrString> for String {
13+
fn from(value: IntOrString) -> Self {
14+
match value {
15+
IntOrString::Int(n) => n.to_string(),
16+
IntOrString::Str(s) => s,
17+
}
18+
}
19+
}
20+
521
/// Deserialize an optional ID type from either a String or an Integer representation.
622
///
723
/// This is used by the codegen to enable String IDs to be deserialized from
@@ -10,18 +26,16 @@ pub fn deserialize_option_id<'de, D>(deserializer: D) -> Result<Option<String>,
1026
where
1127
D: Deserializer<'de>,
1228
{
13-
#[derive(Deserialize)]
14-
#[serde(untagged)]
15-
enum IntOrString {
16-
Int(i64),
17-
Str(String),
18-
}
19-
20-
let res = Option::<IntOrString>::deserialize(deserializer)?;
29+
Option::<IntOrString>::deserialize(deserializer).map(|opt| opt.map(String::from))
30+
}
2131

22-
Ok(match res {
23-
None => None,
24-
Some(IntOrString::Int(n)) => Some(n.to_string()),
25-
Some(IntOrString::Str(s)) => Some(s),
26-
})
32+
/// Deserialize an ID type from either a String or an Integer representation.
33+
///
34+
/// This is used by the codegen to enable String IDs to be deserialized from
35+
/// either Strings or Integers.
36+
pub fn deserialize_id<'de, D>(deserializer: D) -> Result<String, D::Error>
37+
where
38+
D: Deserializer<'de>,
39+
{
40+
IntOrString::deserialize(deserializer).map(String::from)
2741
}

graphql_client_codegen/src/codegen/selection.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -405,10 +405,12 @@ impl ExpandedField<'_> {
405405
qualified_type
406406
};
407407

408-
let id_deserialize_with = if self.field_type == "ID" {
409-
Some(
410-
quote!(#[serde(deserialize_with = "graphql_client::serde_with::deserialize_option_id")]),
411-
)
408+
let is_id = self.field_type == "ID";
409+
let is_required = self.field_type_qualifiers.contains(&GraphqlTypeQualifier::Required);
410+
let id_deserialize_with = if is_id && is_required {
411+
Some(quote!(#[serde(deserialize_with = "graphql_client::serde_with::deserialize_id")]))
412+
} else if is_id {
413+
Some(quote!(#[serde(deserialize_with = "graphql_client::serde_with::deserialize_option_id")]))
412414
} else {
413415
None
414416
};

0 commit comments

Comments
 (0)