use std::collections::HashMap;
use strum_macros::Display;
#[derive(Clone)]
pub enum VariableValues {
Int(i32),
Str(&'static str),
Enum(&'static str),
VecInt(Vec<i32>),
VecStr(Vec<&'static str>),
VecEnum(Vec<&'static str>),
}
type Fields = Vec<either::Either<&'static str, Args>>;
#[derive(Clone)]
pub struct Args {
pub operation: String,
pub fields: Fields,
pub variables: Option<HashMap<&'static str, VariableValues>>,
}
pub fn tabs(level: usize) -> String {
"\t".repeat(level)
}
#[derive(Display)]
#[strum(serialize_all = "snake_case")]
pub enum Operation {
Query,
Mutation,
Subscription,
}
pub struct Builder {
pub raw: String,
}
impl Builder {
pub fn new(operation: Operation, opts: &Args) -> String {
let subfields = Self::parse_sub_fields(&opts, 1).join("\n");
let field = &opts.operation;
format!("{operation} {{\n\t{field} {{\n{subfields}\n\t}}\n}}",)
}
fn parse_sub_fields(args: &Args, level: usize) -> Vec<String> {
let level = level + 1;
let tabs = tabs(level);
args.fields
.clone()
.into_iter()
.map(|arg| match arg {
either::Either::Left(field) => {
format!("{tabs}{field}", field = field)
}
either::Either::Right(args) => {
let field = &args.operation;
let sub_field = Self::parse_sub_fields(&args, level).join("\n");
format!("{tabs}{field} {{\n{sub_field}\n{tabs}}}")
}
})
.collect()
}
}