mirror of
https://github.com/kjuulh/dagger-rs.git
synced 2025-07-25 19:09:22 +02:00
split out codegen parts
This commit is contained in:
89
crates/dagger-codegen/src/codegen.rs
Normal file
89
crates/dagger-codegen/src/codegen.rs
Normal file
@@ -0,0 +1,89 @@
|
||||
use graphql_introspection_query::introspection_response::{
|
||||
FullType, IntrospectionResponse, Schema,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
handlers::{DynHandler, Handlers},
|
||||
predicates::is_custom_scalar_type,
|
||||
};
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub struct CodeGeneration {
|
||||
handlers: Handlers,
|
||||
}
|
||||
|
||||
impl CodeGeneration {
|
||||
pub fn new() -> Self {
|
||||
Self { handlers: vec![] }
|
||||
}
|
||||
|
||||
pub fn generate(&self, schema: &IntrospectionResponse) -> eyre::Result<String> {
|
||||
let code = self.generate_from_schema(
|
||||
schema
|
||||
.as_schema()
|
||||
.schema
|
||||
.as_ref()
|
||||
.ok_or(eyre::anyhow!("could not get schema to generate code from"))?,
|
||||
)?;
|
||||
Ok(code)
|
||||
}
|
||||
|
||||
fn generate_from_schema(&self, schema: &Schema) -> eyre::Result<String> {
|
||||
let mut output = String::new();
|
||||
output.push_str("# code generated by dagger. DO NOT EDIT.");
|
||||
|
||||
let types = get_types(schema)?;
|
||||
//let remaining: Vec<Option<String>> = types.into_iter().map(type_name).collect();
|
||||
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn type_name(&self, t: &FullType) -> Option<String> {
|
||||
let name = t.name.as_ref();
|
||||
if let Some(name) = name {
|
||||
if name.starts_with("_") || !is_custom_scalar_type(t) {
|
||||
return None;
|
||||
}
|
||||
|
||||
return Some(name.replace("Query", "Client"));
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn group_key(&self, t: &FullType) -> Option<DynHandler> {
|
||||
for handler in self.handlers.iter() {
|
||||
if handler.predicate(&t) {
|
||||
return Some(handler.clone());
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn sort_key(&self, t: &FullType) -> (isize, String) {
|
||||
for (i, handler) in self.handlers.iter().enumerate() {
|
||||
if handler.predicate(t) {
|
||||
return (i as isize, t.name.as_ref().unwrap().clone());
|
||||
}
|
||||
}
|
||||
|
||||
return (-1, t.name.as_ref().unwrap().clone());
|
||||
}
|
||||
}
|
||||
|
||||
fn get_types(schema: &Schema) -> eyre::Result<Vec<&FullType>> {
|
||||
let types = schema
|
||||
.types
|
||||
.as_ref()
|
||||
.ok_or(eyre::anyhow!("types not found on schema"))?;
|
||||
|
||||
// 1. Get a list of all types and map it to handlers
|
||||
let types: Vec<&FullType> = types
|
||||
.iter()
|
||||
.map(|t| t.as_ref().map(|t| &t.full_type))
|
||||
.flatten()
|
||||
.collect();
|
||||
|
||||
Ok(types)
|
||||
}
|
82
crates/dagger-codegen/src/handlers/mod.rs
Normal file
82
crates/dagger-codegen/src/handlers/mod.rs
Normal file
@@ -0,0 +1,82 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use genco::prelude::rust::Tokens;
|
||||
use genco::prelude::*;
|
||||
use graphql_introspection_query::introspection_response::FullType;
|
||||
|
||||
pub trait Handler {
|
||||
fn predicate(&self, t: &FullType) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn render(&self, t: &FullType) -> eyre::Result<String> {
|
||||
let mut s = String::new();
|
||||
|
||||
s.push_str("\n");
|
||||
s.push_str(self.render_struct(t)?.to_string()?.as_str());
|
||||
s.push_str("\n");
|
||||
s.push_str(self.render_impl(t)?.to_string()?.as_str());
|
||||
s.push_str("\n");
|
||||
|
||||
Ok(s)
|
||||
}
|
||||
|
||||
fn render_struct(&self, t: &FullType) -> eyre::Result<Tokens> {
|
||||
let name = t.name.as_ref().ok_or(eyre::anyhow!("name not found"))?;
|
||||
|
||||
Ok(quote! {
|
||||
pub $name {} {
|
||||
// TODO: Add fields
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn render_impl(&self, t: &FullType) -> eyre::Result<Tokens> {
|
||||
let name = t.name.as_ref().ok_or(eyre::anyhow!("name not found"))?;
|
||||
|
||||
Ok(quote! {
|
||||
pub $name {} {
|
||||
// TODO: Add fields
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub type DynHandler = Arc<dyn Handler + Send + Sync>;
|
||||
pub type Handlers = Vec<DynHandler>;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use graphql_introspection_query::introspection_response::FullType;
|
||||
|
||||
use super::Handler;
|
||||
|
||||
struct DefaultHandler;
|
||||
impl Handler for DefaultHandler {}
|
||||
|
||||
#[test]
|
||||
fn render_returns_expected() {
|
||||
let handler = DefaultHandler {};
|
||||
let t = FullType {
|
||||
kind: None,
|
||||
name: Some("SomeName".into()),
|
||||
description: None,
|
||||
fields: None,
|
||||
input_fields: None,
|
||||
interfaces: None,
|
||||
enum_values: None,
|
||||
possible_types: None,
|
||||
};
|
||||
|
||||
let res = handler.render(&t).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
res,
|
||||
"
|
||||
pub SomeName {} { }
|
||||
pub SomeName {} { }
|
||||
"
|
||||
.to_string()
|
||||
);
|
||||
}
|
||||
}
|
4671
crates/dagger-codegen/src/lib.rs
Normal file
4671
crates/dagger-codegen/src/lib.rs
Normal file
File diff suppressed because it is too large
Load Diff
11
crates/dagger-codegen/src/models.rs
Normal file
11
crates/dagger-codegen/src/models.rs
Normal file
@@ -0,0 +1,11 @@
|
||||
pub enum Scalars {
|
||||
ID(String),
|
||||
Int(usize),
|
||||
String(String),
|
||||
Float(f64),
|
||||
Boolean(bool),
|
||||
Date(String),
|
||||
DateTime(String),
|
||||
Time(String),
|
||||
Decimal(f64),
|
||||
}
|
30
crates/dagger-codegen/src/predicates.rs
Normal file
30
crates/dagger-codegen/src/predicates.rs
Normal file
@@ -0,0 +1,30 @@
|
||||
use graphql_introspection_query::introspection_response::{self, FullType};
|
||||
|
||||
use crate::models::Scalars;
|
||||
|
||||
pub fn is_scalar_type(t: &FullType) -> bool {
|
||||
if let Some(introspection_response::__TypeKind::SCALAR) = t.kind {
|
||||
return true;
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
pub fn is_custom_scalar_type(t: &FullType) -> bool {
|
||||
if is_scalar_type(t) {
|
||||
// TODO: Insert scalar
|
||||
let _ = match t.name.as_ref().map(|s| s.as_str()) {
|
||||
Some("ID") => Scalars::ID("ID".into()),
|
||||
Some("Int") => Scalars::Int(0),
|
||||
Some("String") => Scalars::String("ID".into()),
|
||||
Some("Float") => Scalars::Float(0.0),
|
||||
Some("Boolean") => Scalars::Boolean(false),
|
||||
Some("Date") => Scalars::Date("ID".into()),
|
||||
Some("DateTime") => Scalars::DateTime("ID".into()),
|
||||
Some("Time") => Scalars::Time("ID".into()),
|
||||
Some("Decimal") => Scalars::Decimal(0.0),
|
||||
Some(_) => return true,
|
||||
None => return false,
|
||||
};
|
||||
}
|
||||
false
|
||||
}
|
Reference in New Issue
Block a user