dagger-rs/crates/dagger-codegen/src/visitor.rs
Kasper Juul Hermansen 4a4c03f3c2
feature/add impl (#6)
* format code

* with object gen and args

* add implementation

* add rust generator

* reset generated code

* add basic output

* reset output

* add object

* add format function

* with opts

* fix vec

* add context to unwrap

* fix arguments

* with function body

* first complete generation: Still missing Vec<Obj>

* run full alpine

* add roadmap item
2023-02-17 12:33:16 +01:00

107 lines
3.0 KiB
Rust

use std::sync::Arc;
use dagger_core::introspection::{FullType, Schema, __TypeKind};
use itertools::Itertools;
pub struct Visitor {
pub schema: Schema,
pub handlers: VisitHandlers,
}
pub type VisitFunc = Arc<dyn Fn(&FullType) -> eyre::Result<()>>;
pub struct VisitHandlers {
pub visit_scalar: VisitFunc,
pub visit_object: VisitFunc,
pub visit_input: VisitFunc,
pub visit_enum: VisitFunc,
}
struct SequenceItem {
kind: __TypeKind,
handler: VisitFunc,
ignore: Option<Vec<String>>,
}
impl Visitor {
pub fn run(&self) -> eyre::Result<()> {
let sequence = vec![
SequenceItem {
kind: __TypeKind::SCALAR,
handler: self.handlers.visit_scalar.clone(),
ignore: Some(vec![
"String".into(),
"Float".into(),
"Int".into(),
"Boolean".into(),
"DateTime".into(),
"ID".into(),
]),
},
SequenceItem {
kind: __TypeKind::INPUT_OBJECT,
handler: self.handlers.visit_input.clone(),
ignore: None,
},
SequenceItem {
kind: __TypeKind::OBJECT,
handler: self.handlers.visit_object.clone(),
ignore: None,
},
SequenceItem {
kind: __TypeKind::ENUM,
handler: self.handlers.visit_enum.clone(),
ignore: None,
},
];
for item in sequence {
self.visit(&item)?;
}
Ok(())
}
fn visit(&self, item: &SequenceItem) -> eyre::Result<()> {
self.schema
.types
.as_ref()
.unwrap()
.into_iter()
.map(|t| t.as_ref().unwrap())
.filter(|t| match t.full_type.kind.as_ref().unwrap() == &item.kind {
true => match (item.ignore.as_ref(), t.full_type.name.as_ref()) {
(Some(ignore), Some(name)) => {
if name.starts_with("__") {
return false;
}
if ignore.contains(name) {
return false;
}
return true;
}
(None, Some(name)) => {
if name.starts_with("__") {
return false;
}
return true;
}
_ => false,
},
false => false,
})
.sorted_by(|a, b| {
a.full_type
.name
.as_ref()
.unwrap()
.cmp(&b.full_type.name.as_ref().unwrap())
})
.map(|t| (*item.handler)(&t.full_type))
.collect::<eyre::Result<Vec<_>>>()?;
Ok(())
}
}