use crate::codegen::config::Config;
use crate::codegen::context::Context;
use crate::codegen::render::cargo::generate_cargo_toml;
use crate::codegen::render::render::Render;
use async_graphql_parser::{parse_schema, types::ServiceDocument};
use std::fs;
use std::io;
use std::path::Path;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum GenericErrors {
#[error("IO issue while trying to access schema")]
NotFoundError(io::Error),
#[error("Parser error")]
ParserError(#[from] async_graphql_parser::Error),
#[error("Can't create the output directory")]
CreateOutputDirectoryError(io::Error),
#[error("Generator error")]
GenericGeneratorError,
#[error("Generic IO issue")]
GenericIOError(#[from] io::Error),
#[error("Config file invalid")]
InvalidConfigError,
#[error("Service {0} not found")]
ServiceNotFoundError(String),
}
fn open<P: AsRef<Path>>(path: P) -> Result<String, GenericErrors> {
fs::read_to_string(path).map_err(GenericErrors::NotFoundError)
}
fn parse<S: AsRef<str>>(schema: S) -> Result<ServiceDocument, GenericErrors> {
parse_schema(&schema).map_err(GenericErrors::ParserError)
}
pub fn generate<P: AsRef<Path>>(path: P, output: P, config: P) -> Result<(), GenericErrors> {
let schema = open(&path).and_then(parse)?;
let config = open(&config).and_then(|config_str| {
toml::from_str::<Config>(&config_str).map_err(|_| GenericErrors::InvalidConfigError)
})?;
let context = Context::new(&output, &schema, &config);
let src = output.as_ref().join(Path::new("src/"));
fs::create_dir_all(src).map_err(GenericErrors::CreateOutputDirectoryError)?;
generate_cargo_toml(output.as_ref().join(Path::new("Cargo.toml")));
let enum_result = context
.enum_types()
.iter()
.map(|x| x.generate())
.collect::<Vec<_>>();
let object_result = context
.object_types()
.iter()
.map(|x| x.generate())
.collect::<Vec<_>>();
context.generate_services()?;
let _ = context.main_file().generate();
println!("|------------------------------|");
println!("| Result |");
println!("|------------------------------|");
println!("Enum: {:?}", &enum_result);
println!("Objects: {:?}", &object_result);
Ok(())
}