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
143
Cargo.lock
generated
143
Cargo.lock
generated
|
|
@ -82,6 +82,36 @@ dependencies = [
|
|||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
|
||||
|
||||
[[package]]
|
||||
name = "async-graphql-parser"
|
||||
version = "7.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8531ee6d292c26df31c18c565ff22371e7bdfffe7f5e62b69537db0b8fd554dc"
|
||||
dependencies = [
|
||||
"async-graphql-value",
|
||||
"pest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-graphql-value"
|
||||
version = "7.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "741110dda927420a28fbc1c310543d3416f789a6ba96859c2c265843a0a96887"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"indexmap",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.4.0"
|
||||
|
|
@ -144,6 +174,9 @@ name = "bytes"
|
|||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "camino"
|
||||
|
|
@ -233,6 +266,12 @@ dependencies = [
|
|||
"powerfmt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
|
|
@ -407,6 +446,7 @@ checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652"
|
|||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -421,6 +461,15 @@ version = "1.70.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.14"
|
||||
|
|
@ -464,7 +513,7 @@ checksum = "412e2cf22cb560469db5b211c594ff9dcd490c6964e284ea64eddffe41c2249c"
|
|||
dependencies = [
|
||||
"miette",
|
||||
"num",
|
||||
"thiserror",
|
||||
"thiserror 1.0.69",
|
||||
"winnow",
|
||||
]
|
||||
|
||||
|
|
@ -508,6 +557,12 @@ version = "0.4.25"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f"
|
||||
|
||||
[[package]]
|
||||
name = "maplit"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
|
||||
|
||||
[[package]]
|
||||
name = "matchers"
|
||||
version = "0.1.0"
|
||||
|
|
@ -540,7 +595,7 @@ dependencies = [
|
|||
"syntect",
|
||||
"terminal_size",
|
||||
"textwrap",
|
||||
"thiserror",
|
||||
"thiserror 1.0.69",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
|
|
@ -756,6 +811,17 @@ dependencies = [
|
|||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest"
|
||||
version = "2.7.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"thiserror 2.0.11",
|
||||
"ucd-trie",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.16"
|
||||
|
|
@ -790,6 +856,7 @@ dependencies = [
|
|||
"tokio-stream",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"trustfall",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1025,6 +1092,9 @@ name = "smallvec"
|
|||
version = "1.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
|
|
@ -1091,7 +1161,7 @@ dependencies = [
|
|||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"thiserror 1.0.69",
|
||||
"walkdir",
|
||||
"yaml-rust",
|
||||
]
|
||||
|
|
@ -1122,7 +1192,16 @@ version = "1.0.69"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
"thiserror-impl 1.0.69",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "2.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc"
|
||||
dependencies = [
|
||||
"thiserror-impl 2.0.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1136,6 +1215,17 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "2.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.1.8"
|
||||
|
|
@ -1325,6 +1415,51 @@ dependencies = [
|
|||
"tracing-log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "trustfall"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2c4d6f50f158998ff48a905a4f12e918b9dfd1274c0711c0f4485d8f7ff015e"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"trustfall_core",
|
||||
"trustfall_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "trustfall_core"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "363322af9d4d04fb0e298d8e9f97d9ef316a796f6f4e5f241060ad50a07d0334"
|
||||
dependencies = [
|
||||
"async-graphql-parser",
|
||||
"async-graphql-value",
|
||||
"itertools",
|
||||
"maplit",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"smallvec",
|
||||
"thiserror 1.0.69",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "trustfall_derive"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fb14eb4f23b3b669d232a5c7d2b3d6c89ad9e15be1cbdd2c1e14d87d62569ec"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ucd-trie"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.16"
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,3 +15,9 @@ changelog "2025-02-01" {
|
|||
version "0.1.0"
|
||||
kind "Feature"
|
||||
}
|
||||
|
||||
changelog "2025-02-07" {
|
||||
title "Added trustfall as a query frontend"
|
||||
version "0.1.0"
|
||||
kind "Feature"
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue