use async_graphql::parser::types::{DocumentOperations, ExecutableDocument};
use itertools::Itertools;
#[derive(Debug)]
pub struct Script {
pub(crate) requests: Vec<async_graphql::Request>,
}
impl From<async_graphql::Request> for Script {
fn from(value: async_graphql::Request) -> Self {
Self {
requests: vec![value],
}
}
}
impl From<&str> for Script {
fn from(value: &str) -> Self {
Self::parse(value)
}
}
impl From<String> for Script {
fn from(value: String) -> Self {
Self::parse(value.as_str())
}
}
impl Script {
pub fn variables(mut self, map: async_graphql::Value) -> Self {
for req in self.requests.iter_mut() {
req.variables = async_graphql::Variables::from_value(map.clone());
}
self
}
pub fn upload(mut self, var_path: &str, upload: async_graphql::UploadValue) -> Self {
for req in self.requests.iter_mut() {
req.set_upload(var_path, upload.try_clone().unwrap())
}
self
}
fn parse(source_code: &str) -> Self {
Self {
requests: match async_graphql::parser::parse_query(source_code).unwrap() {
doc @ ExecutableDocument {
operations: DocumentOperations::Single(_),
..
} => {
let mut req = async_graphql::Request::new(source_code);
req.set_parsed_query(doc);
[req].into()
}
ExecutableDocument {
operations: DocumentOperations::Multiple(map),
fragments,
} => map
.into_iter()
.sorted_by_key(|(_, def)| def.pos)
.map(|(name, def)| {
let doc = ExecutableDocument {
operations: DocumentOperations::Single(def),
fragments: fragments.clone(),
};
let mut req =
async_graphql::Request::new(source_code).operation_name(&*name);
req.set_parsed_query(doc);
req
})
.collect(),
},
}
}
}