Start using trustfall to query the repo
Signed-off-by: Marcel Müller <neikos@neikos.email>
This commit is contained in:
parent
68fbc3ce25
commit
6501b42328
5 changed files with 277 additions and 18 deletions
|
|
@ -18,6 +18,7 @@ tokio = { version = "1.43.0", features = ["full"] }
|
|||
tokio-stream = { version = "0.1.17", features = ["full"] }
|
||||
tracing = "0.1.41"
|
||||
tracing-subscriber = { version = "0.3.19", features = ["env-filter"] }
|
||||
trustfall = "0.8.1"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
|
|
|||
|
|
@ -1,11 +1,22 @@
|
|||
#![allow(dead_code)]
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
use camino::Utf8PathBuf;
|
||||
use clap::Parser;
|
||||
use clap::Subcommand;
|
||||
use clap::ValueHint;
|
||||
use human_panic::Metadata;
|
||||
use parsing::Definition;
|
||||
use parsing::Record;
|
||||
use tracing::info;
|
||||
use trustfall::execute_query;
|
||||
use trustfall::provider::field_property;
|
||||
use trustfall::provider::resolve_property_with;
|
||||
use trustfall::provider::Adapter;
|
||||
use trustfall::FieldValue;
|
||||
use trustfall::Schema;
|
||||
|
||||
mod config;
|
||||
mod parsing;
|
||||
|
|
@ -46,18 +57,127 @@ async fn main() -> miette::Result<()> {
|
|||
let config = config::parse_config(&args.config).await?;
|
||||
let root_folder = args.root_folder.as_ref().unwrap_or(&config.root_folder);
|
||||
|
||||
let load_records = async {
|
||||
let definitions = parsing::load_definitions(&root_folder.join("definitions")).await?;
|
||||
parsing::load_records(root_folder, &definitions).await
|
||||
};
|
||||
let definitions = parsing::load_definitions(&root_folder.join("definitions")).await?;
|
||||
|
||||
let records = parsing::load_records(root_folder, &definitions).await?;
|
||||
|
||||
let schema = to_schema(&definitions);
|
||||
|
||||
let result = execute_query(
|
||||
&schema,
|
||||
Arc::new(PlaixtAdapter {
|
||||
records: records.clone(),
|
||||
}),
|
||||
"{
|
||||
RecordsAll {
|
||||
at @output
|
||||
kind @output @filter(op: \"=\", value: [\"$foobar\"])
|
||||
}
|
||||
}",
|
||||
[(
|
||||
Arc::from("foobar"),
|
||||
FieldValue::String(Arc::from("changelog")),
|
||||
)]
|
||||
.into(),
|
||||
)
|
||||
.unwrap()
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
match args.mode {
|
||||
ArgMode::Dump => {
|
||||
let records = load_records.await?;
|
||||
|
||||
info!("Got records: {records:#?}");
|
||||
info!("Got records: {result:#?}");
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn to_schema(_definitions: &BTreeMap<String, Vec<Definition>>) -> Schema {
|
||||
Schema::parse(format!(
|
||||
r#"schema {{
|
||||
query: RootSchemaQuery
|
||||
}}
|
||||
{}
|
||||
|
||||
|
||||
type RootSchemaQuery {{
|
||||
RecordsAll: [Record!]!
|
||||
}}
|
||||
interface Record {{
|
||||
at: String!,
|
||||
kind: String!,
|
||||
}}
|
||||
"#,
|
||||
Schema::ALL_DIRECTIVE_DEFINITIONS
|
||||
))
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
struct PlaixtAdapter {
|
||||
records: Vec<Record>,
|
||||
}
|
||||
|
||||
impl<'a> Adapter<'a> for PlaixtAdapter {
|
||||
type Vertex = Record;
|
||||
|
||||
fn resolve_starting_vertices(
|
||||
&self,
|
||||
edge_name: &Arc<str>,
|
||||
_parameters: &trustfall::provider::EdgeParameters,
|
||||
_resolve_info: &trustfall::provider::ResolveInfo,
|
||||
) -> trustfall::provider::VertexIterator<'a, Self::Vertex> {
|
||||
match edge_name.as_ref() {
|
||||
"RecordsAll" => Box::new(self.records.clone().into_iter()),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_property<V: trustfall::provider::AsVertex<Self::Vertex> + 'a>(
|
||||
&self,
|
||||
contexts: trustfall::provider::ContextIterator<'a, V>,
|
||||
type_name: &Arc<str>,
|
||||
property_name: &Arc<str>,
|
||||
_resolve_info: &trustfall::provider::ResolveInfo,
|
||||
) -> trustfall::provider::ContextOutcomeIterator<'a, V, trustfall::FieldValue> {
|
||||
match (type_name.as_ref(), property_name.as_ref()) {
|
||||
(_, "__typename") => Box::new(contexts.map(|ctx| {
|
||||
let value = match ctx.active_vertex() {
|
||||
Some(_record) => "Record".into(),
|
||||
None => FieldValue::Null,
|
||||
};
|
||||
|
||||
(ctx, value)
|
||||
})),
|
||||
("Record", "at") => {
|
||||
resolve_property_with(contexts, field_property!(at, { at.to_string().into() }))
|
||||
}
|
||||
("Record", "kind") => resolve_property_with(contexts, field_property!(kind)),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_neighbors<V: trustfall::provider::AsVertex<Self::Vertex> + 'a>(
|
||||
&self,
|
||||
_contexts: trustfall::provider::ContextIterator<'a, V>,
|
||||
_type_name: &Arc<str>,
|
||||
_edge_name: &Arc<str>,
|
||||
_parameters: &trustfall::provider::EdgeParameters,
|
||||
_resolve_info: &trustfall::provider::ResolveEdgeInfo,
|
||||
) -> trustfall::provider::ContextOutcomeIterator<
|
||||
'a,
|
||||
V,
|
||||
trustfall::provider::VertexIterator<'a, Self::Vertex>,
|
||||
> {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
fn resolve_coercion<V: trustfall::provider::AsVertex<Self::Vertex> + 'a>(
|
||||
&self,
|
||||
_contexts: trustfall::provider::ContextIterator<'a, V>,
|
||||
_type_name: &Arc<str>,
|
||||
_coerce_to_type: &Arc<str>,
|
||||
_resolve_info: &trustfall::provider::ResolveInfo,
|
||||
) -> trustfall::provider::ContextOutcomeIterator<'a, V, bool> {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ use miette::NamedSource;
|
|||
use owo_colors::OwoColorize;
|
||||
use tokio_stream::wrappers::ReadDirStream;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Record {
|
||||
pub(crate) kind: String,
|
||||
pub(crate) at: Timestamp,
|
||||
|
|
@ -82,8 +82,7 @@ pub(crate) fn parse_record(
|
|||
.map(|field| {
|
||||
let Some(get) = field.get(0) else {
|
||||
return Err(miette::diagnostic!(
|
||||
labels =
|
||||
vec![LabeledSpan::new_primary_with_span(None, at_entry.span())],
|
||||
labels = vec![LabeledSpan::new_primary_with_span(None, at_entry.span())],
|
||||
"This datetime should be a string formatted as RFC3339."
|
||||
))?;
|
||||
};
|
||||
|
|
@ -143,9 +142,8 @@ pub(crate) async fn load_records(
|
|||
})
|
||||
.flat_map(|val| futures::stream::iter(val.transpose()))
|
||||
.and_then(|(name, bytes)| async move {
|
||||
parse_record(&bytes, definitions).map_err(|e| {
|
||||
e.with_source_code(NamedSource::new(name, bytes).with_language("kdl"))
|
||||
})
|
||||
parse_record(&bytes, definitions)
|
||||
.map_err(|e| e.with_source_code(NamedSource::new(name, bytes).with_language("kdl")))
|
||||
})
|
||||
.map(|val| val.map(|recs| futures::stream::iter(recs).map(Ok::<_, miette::Report>)))
|
||||
.try_flatten()
|
||||
|
|
@ -344,4 +342,3 @@ pub(crate) async fn load_definitions(
|
|||
|
||||
Ok(defs)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue