Make filesystem types handle their path impl

Signed-off-by: Marcel Müller <neikos@neikos.email>
This commit is contained in:
Marcel Müller 2025-02-09 20:16:07 +01:00
parent 11c3a8de94
commit a6406ebd5a
7 changed files with 78 additions and 141 deletions

101
Cargo.lock generated
View file

@ -180,15 +180,6 @@ version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36"
[[package]]
name = "block-buffer"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
"generic-array",
]
[[package]]
name = "bumpalo"
version = "3.17.0"
@ -296,15 +287,6 @@ version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]]
name = "cpufeatures"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
dependencies = [
"libc",
]
[[package]]
name = "crc32fast"
version = "1.4.2"
@ -314,16 +296,6 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "crypto-common"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [
"generic-array",
"typenum",
]
[[package]]
name = "deranged"
version = "0.3.11"
@ -346,16 +318,6 @@ dependencies = [
"syn",
]
[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"crypto-common",
]
[[package]]
name = "displaydoc"
version = "0.2.5"
@ -404,16 +366,6 @@ version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
[[package]]
name = "filesystem-trustfall-adapter"
version = "0.1.1"
dependencies = [
"serde",
"serde_json",
"sha256",
"trustfall",
]
[[package]]
name = "flate2"
version = "1.0.35"
@ -543,16 +495,6 @@ dependencies = [
"slab",
]
[[package]]
name = "generic-array"
version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "getrandom"
version = "0.3.1"
@ -602,12 +544,6 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "hex"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "http"
version = "0.2.12"
@ -1343,7 +1279,6 @@ version = "0.1.0"
dependencies = [
"camino",
"clap",
"filesystem-trustfall-adapter",
"futures",
"human-panic",
"jiff",
@ -1667,30 +1602,6 @@ dependencies = [
"serde",
]
[[package]]
name = "sha2"
version = "0.10.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]]
name = "sha256"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18278f6a914fa3070aa316493f7d2ddfb9ac86ebc06fa3b83bffda487e9065b0"
dependencies = [
"async-trait",
"bytes",
"hex",
"sha2",
"tokio",
]
[[package]]
name = "sharded-slab"
version = "0.1.7"
@ -2181,12 +2092,6 @@ version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
[[package]]
name = "typenum"
version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
[[package]]
name = "ucd-trie"
version = "0.1.7"
@ -2261,12 +2166,6 @@ version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "walkdir"
version = "2.5.0"

View file

@ -8,7 +8,6 @@ license.workspace = true
[dependencies]
camino = { version = "1.1.9", features = ["serde", "serde1"] }
clap = { version = "4.5.27", features = ["derive"] }
filesystem-trustfall-adapter = { version = "0.1.1", path = "../../../trustfall-adapters-zimbopro/filesystem-trustfall-adapter" }
futures = "0.3.31"
human-panic = "2.0.2"
jiff = "0.1.28"

View file

@ -4,6 +4,7 @@ use std::sync::Arc;
use std::sync::OnceLock;
use paperless_rs::PaperlessClient;
use tracing::debug;
use trustfall::provider::resolve_coercion_using_schema;
use trustfall::provider::resolve_property_with;
use trustfall::provider::AsVertex;
@ -91,24 +92,18 @@ impl<'a> trustfall::provider::Adapter<'a> for Adapter {
if property_name.as_ref() == "__typename" {
return resolve_property_with(contexts, |vertex| vertex.typename().into());
}
debug!(?type_name, ?property_name, "Resolving property");
match type_name.as_ref() {
"PaperlessDocument" => super::properties::resolve_paperless_document_property(
contexts,
property_name.as_ref(),
resolve_info,
),
"Path" => super::properties::resolve_path_property(
contexts,
property_name.as_ref(),
resolve_info,
),
"File" => super::properties::resolve_file_property(
contexts,
property_name.as_ref(),
resolve_info,
),
"Directory" => super::properties::resolve_directory_property(
"Path" | "File" | "Directory" => super::properties::resolve_fs_property(
contexts,
type_name.as_ref(),
property_name.as_ref(),
resolve_info,
),
@ -159,12 +154,13 @@ impl<'a> trustfall::provider::Adapter<'a> for Adapter {
fn resolve_coercion<V: AsVertex<Self::Vertex> + 'a>(
&self,
contexts: ContextIterator<'a, V>,
_type_name: &Arc<str>,
type_name: &Arc<str>,
coerce_to_type: &Arc<str>,
_resolve_info: &ResolveInfo,
) -> ContextOutcomeIterator<'a, V, bool> {
let schema = self.schema.clone();
let coerce_to_type = coerce_to_type.clone();
debug!(?coerce_to_type, ?type_name, "Trying to coerce");
Box::new(contexts.map(move |ctx| {
let subtypes: BTreeSet<_> = schema
@ -176,8 +172,15 @@ impl<'a> trustfall::provider::Adapter<'a> for Adapter {
None => (ctx, false),
Some(vertex) => {
let typename = vertex.typename();
let can_coerce = subtypes.contains(typename);
(ctx, can_coerce)
debug!(?coerce_to_type, ?vertex, "Trying to coerce");
if let Some(rec) = vertex.as_record() {
let is_rec = coerce_to_type.starts_with("p_");
let is_kind = rec.kind == coerce_to_type.as_ref()[2..];
(ctx, is_rec && is_kind)
} else {
let can_coerce = subtypes.contains(typename);
(ctx, can_coerce)
}
}
}
}))

View file

@ -1,6 +1,7 @@
use std::collections::BTreeMap;
use std::sync::Arc;
use camino::Utf8PathBuf;
use trustfall::provider::resolve_neighbors_with;
use trustfall::provider::AsVertex;
use trustfall::provider::ContextIterator;
@ -11,6 +12,7 @@ use trustfall::provider::VertexIterator;
use super::Vertex;
use crate::parsing::DefinitionKind;
use crate::parsing::Record;
pub(super) fn resolve_directory_edge<'a, V: AsVertex<Vertex> + 'a>(
contexts: ContextIterator<'a, V>,
@ -76,10 +78,19 @@ pub(super) fn resolve_record_edge<'a, V: AsVertex<Vertex> + 'a>(
let def = &definitions[&rec.kind][edge_name.as_ref()];
match def {
DefinitionKind::Path => Box::new(std::iter::once(Vertex::Path(
rec.fields[edge_name.as_ref()].as_string().unwrap().into(),
))),
DefinitionKind::Path => Box::new(std::iter::once(path_from_rec(rec, &edge_name))),
_ => unreachable!("Only `Path` can appear as edge for now"),
}
})
}
fn path_from_rec(rec: &Record, edge_name: &str) -> Vertex {
let pathb = Utf8PathBuf::from(rec.fields[edge_name].as_string().unwrap());
if pathb.is_file() {
Vertex::File(pathb)
} else if pathb.is_dir() {
Vertex::Directory(pathb)
} else {
Vertex::Path(pathb)
}
}

View file

@ -1,8 +1,6 @@
use std::collections::BTreeMap;
use std::sync::Arc;
use kdl::KdlValue;
use paperless_rs::PaperlessClient;
use trustfall::provider::field_property;
use trustfall::provider::resolve_property_with;
use trustfall::provider::AsVertex;
@ -13,26 +11,49 @@ use trustfall::FieldValue;
use super::vertex::Vertex;
pub(super) fn resolve_fs_property<'a, V: AsVertex<Vertex> + 'a>(
contexts: ContextIterator<'a, V>,
type_name: &str,
property_name: &str,
resolve_info: &ResolveInfo,
) -> ContextOutcomeIterator<'a, V, FieldValue> {
match (type_name, property_name) {
(_, "exists" | "basename" | "path") => {
resolve_path_property(contexts, property_name, resolve_info)
}
("Directory", _) => resolve_directory_property(contexts, property_name, resolve_info),
("File", _) => resolve_file_property(contexts, property_name, resolve_info),
_ => {
unreachable!(
"attempted to read unexpected property '{property_name}' on type '{type_name}'"
)
}
}
}
pub(super) fn resolve_path_property<'a, V: AsVertex<Vertex> + 'a>(
contexts: ContextIterator<'a, V>,
property_name: &str,
_resolve_info: &ResolveInfo,
) -> ContextOutcomeIterator<'a, V, FieldValue> {
match property_name {
"exists" => resolve_property_with(contexts, move |v: &Vertex| {
let path = v.as_path().expect("vertex was not a Path");
path.exists().into()
"exists" => resolve_property_with(contexts, move |v: &Vertex| match v {
Vertex::Path(p) | Vertex::File(p) | Vertex::Directory(p) => p.exists().into(),
_ => {
panic!("Vertex was not a filesystem type")
}
}),
"basename" => resolve_property_with(contexts, move |v: &Vertex| {
let path = v.as_path().expect("vertex was not a Path");
path.file_name().into()
"basename" => resolve_property_with(contexts, move |v: &Vertex| match v {
Vertex::Path(p) | Vertex::File(p) | Vertex::Directory(p) => p.file_name().into(),
_ => {
panic!("Vertex was not a filesystem type")
}
}),
"path" => resolve_property_with(contexts, move |v: &Vertex| {
let path = v.as_path().expect("vertex was not a Path");
path.to_string().into()
"path" => resolve_property_with(contexts, move |v: &Vertex| match v {
Vertex::Path(p) | Vertex::File(p) | Vertex::Directory(p) => p.to_string().into(),
_ => {
panic!("Vertex was not a filesystem type")
}
}),
_ => {
unreachable!("attempted to read unexpected property '{property_name}' on type 'Path'")

View file

@ -25,3 +25,7 @@ changelog "2025-02-07" {
file_test "2025-02-08" {
path "Cargo.toml"
}
file_test "2025-02-08" {
path "/etc"
}

16
query
View file

@ -1,12 +1,12 @@
{
Plaixt__RecordsAll {
... on Plaixt__file_test {
at @output
kind @output
fields {
path {
... on fs__File {
size @output
Records {
... on p_file_test {
_at @output
_kind @output
path {
... on Directory {
Children @recurse(depth: 10) {
path @output
}
}
}