From 77e5783969f6b4804f3d22314ef66afe83c36cf1 Mon Sep 17 00:00:00 2001 From: Edmondo Porcu Date: Wed, 5 Feb 2025 02:50:54 -0500 Subject: [PATCH] Adding a pretty debug implementation to overcome escaping of strings as a part of macro reading from files --- graphql_client/src/lib.rs | 24 +++++++++++++++- graphql_client/tests/readable_debug.rs | 40 ++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 graphql_client/tests/readable_debug.rs diff --git a/graphql_client/src/lib.rs b/graphql_client/src/lib.rs index 67364730..4e80ea4e 100644 --- a/graphql_client/src/lib.rs +++ b/graphql_client/src/lib.rs @@ -89,7 +89,7 @@ pub trait GraphQLQuery { } /// The form in which queries are sent over HTTP in most implementations. This will be built using the [`GraphQLQuery`] trait normally. -#[derive(Debug, Serialize, Deserialize)] +#[derive(Serialize, Deserialize)] pub struct QueryBody { /// The values for the variables. They must match those declared in the queries. This should be the `Variables` struct from the generated module corresponding to the query. pub variables: Variables, @@ -100,6 +100,28 @@ pub struct QueryBody { pub operation_name: &'static str, } +struct PrettyStr<'a>(&'a str); + +impl<'a> fmt::Debug for PrettyStr<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // Use `{}` (Display) instead of `{:?}` (Debug) to avoid escaping newlines. + write!(f, "\"{}\"", self.0) + } +} + +impl fmt::Debug for QueryBody { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("QueryBody") + .field("variables", &self.variables) + // Replace the escaped literal "\n" with actual newline characters. + // This is necessary because when using code-generation, + // multi-line strings in macros are escaped and become a single + // line string in the generated code + .field("query", &PrettyStr(self.query)) + .field("operation_name", &self.operation_name) + .finish() + } +} /// Represents a location inside a query string. Used in errors. See [`Error`]. #[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq, Eq)] pub struct Location { diff --git a/graphql_client/tests/readable_debug.rs b/graphql_client/tests/readable_debug.rs new file mode 100644 index 00000000..d9a01590 --- /dev/null +++ b/graphql_client/tests/readable_debug.rs @@ -0,0 +1,40 @@ +use graphql_client::*; +use opt_query::Param; + +#[derive(GraphQLQuery)] +#[graphql( + query_path = "tests/default/query.graphql", + schema_path = "tests/default/schema.graphql", + variables_derives = "Default, Debug" +)] +struct OptQuery; + +fn normalize_whitespace(s: &str) -> String { + s.lines() + .map(str::trim) + .filter(|line| !line.is_empty()) + .collect::>() + .join("\n") +} + +#[test] +fn query_is_formatted_correctly() { + let variables = opt_query::Variables { + param: Some(Param::AUTHOR), + }; + let query = OptQuery::build_query(variables); + let debug_output = format!("{:#?}", query); + + let original_query = include_str!("default/query.graphql"); + + // Normalize both for comparison + let normalized_debug_output = normalize_whitespace(&debug_output); + let normalized_original_query = normalize_whitespace(original_query); + + assert!( + normalized_debug_output.contains(&normalized_original_query), + "Debug output did not contain the expected query.\nDebug output:\n{}\n\nExpected query:\n{}", + normalized_debug_output, + normalized_original_query + ); +}