Skip to content

Commit

Permalink
WIP Use graphql_client_codegen with output query string
Browse files Browse the repository at this point in the history
  • Loading branch information
dphm committed Jan 11, 2024
1 parent 4816796 commit b787f92
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 55 deletions.
30 changes: 27 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions example_with_targets/.target_a.output.graphql

This file was deleted.

3 changes: 0 additions & 3 deletions example_with_targets/.target_b.output.graphql

This file was deleted.

3 changes: 0 additions & 3 deletions shopify_function/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,3 @@ serde = { version = "1.0.13", features = ["derive"] }
serde_json = "1.0"
anyhow = "1.0.62"
shopify_function_macro = { version = "0.5.0", path = "../shopify_function_macro" }

[dev-dependencies]
graphql_client = "0.13.0"
1 change: 1 addition & 0 deletions shopify_function_macro/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ syn = { version = "1.0", features = ["full"] }
quote = "1.0"
proc-macro2 = "1.0.43"
convert_case = "0.6.0"
graphql_client_codegen = { git = "https://github.com/dphm/graphql-client.git", branch = "query-string" }
91 changes: 48 additions & 43 deletions shopify_function_macro/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use convert_case::{Case, Casing};
use std::io::Write;
use graphql_client_codegen::{
generate_module_token_stream, generate_module_token_stream_from_string, CodegenMode,
GraphQLClientCodegenOptions,
};
use std::path::Path;

use proc_macro2::{Ident, Span, TokenStream, TokenTree};
Expand Down Expand Up @@ -237,23 +240,20 @@ pub fn shopify_function_target(
|module_name| Ident::new(module_name.value().as_str(), Span::mixed_site()),
);

let query_path = args.query_path.expect("No value given for query_path");
let schema_path = args.schema_path.expect("No value given for schema_path");
let output_query_file_name = format!(".{}{}", &target_handle_string, OUTPUT_QUERY_FILE_NAME);

let input_struct = generate_struct(
"Input",
query_path.value().as_str(),
schema_path.value().as_str(),
let dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
let query_path = Path::new(&dir).join(
args.query_path
.expect("No value given for query_path")
.value()
.as_str(),
);
let output_struct = generate_struct(
"Output",
&output_query_file_name,
schema_path.value().as_str(),
let schema_path = Path::new(&dir).join(
args.schema_path
.expect("No value given for schema_path")
.value()
.as_str(),
);
if let Err(error) = extract_shopify_function_return_type(&ast) {
return error.to_compile_error().into();
}

let output_result_type = extract_shopify_function_return_type(&ast)
.unwrap()
.to_token_stream()
Expand All @@ -263,8 +263,12 @@ pub fn shopify_function_target(
output_result_type,
&target_handle_string.to_case(Case::Camel)
);
let input_struct = generate_input_struct(query_path, &schema_path);
let output_struct = generate_output_struct(&output_query, &schema_path);

write_output_query_file(&output_query_file_name, &output_query);
if let Err(error) = extract_shopify_function_return_type(&ast) {
return error.to_compile_error().into();
}

let input_stream = args
.input_stream
Expand Down Expand Up @@ -318,8 +322,6 @@ fn extract_attr(attrs: &TokenStream, attr: &str) -> String {
value.as_str()[1..value.len() - 1].to_string()
}

const OUTPUT_QUERY_FILE_NAME: &str = ".output.graphql";

/// Generate the types to interact with Shopify's API.
///
/// The macro generates two inline modules: `input` and `output`. The
Expand All @@ -340,15 +342,18 @@ const OUTPUT_QUERY_FILE_NAME: &str = ".output.graphql";
pub fn generate_types(attr: proc_macro::TokenStream) -> proc_macro::TokenStream {
let params = TokenStream::from(attr);

let query_path = extract_attr(&params, "query_path");
let schema_path = extract_attr(&params, "schema_path");
let query_path_attr = extract_attr(&params, "query_path");
let schema_path_attr = extract_attr(&params, "schema_path");

let dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
let schema_path = Path::new(&dir).join(schema_path_attr);

let input_query_path = Path::new(&dir).join(query_path_attr);
let input_struct = generate_input_struct(input_query_path, &schema_path);

let input_struct = generate_struct("Input", &query_path, &schema_path);
let output_struct = generate_struct("Output", OUTPUT_QUERY_FILE_NAME, &schema_path);
let output_query =
"mutation Output($result: FunctionResult!) {\n handleResult(result: $result)\n}\n";

write_output_query_file(OUTPUT_QUERY_FILE_NAME, output_query);
let output_struct = generate_output_struct(output_query, &schema_path);

quote! {
#input_struct
Expand All @@ -357,29 +362,29 @@ pub fn generate_types(attr: proc_macro::TokenStream) -> proc_macro::TokenStream
.into()
}

fn generate_struct(name: &str, query_path: &str, schema_path: &str) -> TokenStream {
let name_ident = Ident::new(name, Span::mixed_site());
fn generate_input_struct(
query_path: std::path::PathBuf,
schema_path: &Path,
) -> proc_macro2::TokenStream {
let options = GraphQLClientCodegenOptions::new(CodegenMode::Derive);
let token_stream = generate_module_token_stream(query_path, schema_path, options)
.expect("Error generating Input struct");

quote! {
#[derive(graphql_client::GraphQLQuery, Clone, Debug, serde::Deserialize, PartialEq)]
#[graphql(
query_path = #query_path,
schema_path = #schema_path,
response_derives = "Clone,Debug,PartialEq,Deserialize,Serialize",
variables_derives = "Clone,Debug,PartialEq,Deserialize",
skip_serializing_none
)]
pub struct #name_ident;
#token_stream
pub struct Input;
}
}

fn write_output_query_file(output_query_file_name: &str, contents: &str) {
let cargo_manifest_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
let output_query_path = Path::new(&cargo_manifest_dir).join(output_query_file_name);
std::fs::File::create(output_query_path)
.expect("Could not create output query file")
.write_all(contents.as_bytes())
.unwrap_or_else(|_| panic!("Could not write to {}", output_query_file_name));
fn generate_output_struct(query: &str, schema_path: &Path) -> proc_macro2::TokenStream {
let options = GraphQLClientCodegenOptions::new(CodegenMode::Derive);
let token_stream = generate_module_token_stream_from_string(query, schema_path, &options)
.expect("Error generating Output struct");

quote! {
#token_stream
pub struct Output;
}
}

#[cfg(test)]
Expand Down

0 comments on commit b787f92

Please sign in to comment.