filesystem_trustfall_adapter/
adapter_impl.rs1use std::sync::{Arc, OnceLock};
2
3use trustfall::{
4 provider::{
5 resolve_coercion_using_schema, resolve_property_with, AsVertex, ContextIterator,
6 ContextOutcomeIterator, EdgeParameters, ResolveEdgeInfo, ResolveInfo, Typename,
7 VertexIterator,
8 },
9 FieldValue, Schema,
10};
11
12use super::vertex::Vertex;
13
14static SCHEMA: OnceLock<Schema> = OnceLock::new();
15
16#[non_exhaustive]
17#[derive(Debug)]
18pub struct FileSystemAdapter {}
19
20impl Default for FileSystemAdapter {
21 fn default() -> Self {
22 Self::new()
23 }
24}
25
26impl FileSystemAdapter {
27 pub const SCHEMA_TEXT: &'static str = include_str!("./schema.graphql");
28
29 pub fn schema() -> &'static Schema {
30 SCHEMA.get_or_init(|| Schema::parse(Self::SCHEMA_TEXT).expect("not a valid schema"))
31 }
32
33 pub fn new() -> Self {
34 Self {}
35 }
36}
37
38impl<'a> trustfall::provider::Adapter<'a> for FileSystemAdapter {
39 type Vertex = Vertex;
40
41 fn resolve_starting_vertices(
42 &self,
43 edge_name: &Arc<str>,
44 parameters: &EdgeParameters,
45 resolve_info: &ResolveInfo,
46 ) -> VertexIterator<'a, Self::Vertex> {
47 match edge_name.as_ref() {
48 "Path" => {
49 let path: &str = parameters
50 .get("path")
51 .expect(
52 "failed to find parameter 'path' when resolving 'Path' starting vertices",
53 )
54 .as_str()
55 .expect(
56 "unexpected null or other incorrect datatype for Trustfall type 'String!'",
57 );
58 super::entrypoints::path(path, resolve_info)
59 }
60 _ => {
61 unreachable!(
62 "attempted to resolve starting vertices for unexpected edge name: {edge_name}"
63 )
64 }
65 }
66 }
67
68 fn resolve_property<V: AsVertex<Self::Vertex> + 'a>(
69 &self,
70 contexts: ContextIterator<'a, V>,
71 type_name: &Arc<str>,
72 property_name: &Arc<str>,
73 resolve_info: &ResolveInfo,
74 ) -> ContextOutcomeIterator<'a, V, FieldValue> {
75 if property_name.as_ref() == "__typename" {
76 return resolve_property_with(contexts, |vertex| vertex.typename().into());
77 }
78 match type_name.as_ref() {
79 "File" => super::properties::resolve_file_property(
80 contexts,
81 property_name.as_ref(),
82 resolve_info,
83 ),
84 "Folder" => super::properties::resolve_folder_property(
85 contexts,
86 property_name.as_ref(),
87 resolve_info,
88 ),
89 "Path" => super::properties::resolve_path_property(
90 contexts,
91 property_name.as_ref(),
92 resolve_info,
93 ),
94 _ => {
95 unreachable!(
96 "attempted to read property '{property_name}' on unexpected type: {type_name}"
97 )
98 }
99 }
100 }
101
102 fn resolve_neighbors<V: AsVertex<Self::Vertex> + 'a>(
103 &self,
104 contexts: ContextIterator<'a, V>,
105 type_name: &Arc<str>,
106 edge_name: &Arc<str>,
107 parameters: &EdgeParameters,
108 resolve_info: &ResolveEdgeInfo,
109 ) -> ContextOutcomeIterator<'a, V, VertexIterator<'a, Self::Vertex>> {
110 match type_name.as_ref() {
111 "Folder" => super::edges::resolve_folder_edge(
112 contexts,
113 edge_name.as_ref(),
114 parameters,
115 resolve_info,
116 ),
117 _ => {
118 unreachable!(
119 "attempted to resolve edge '{edge_name}' on unexpected type: {type_name}"
120 )
121 }
122 }
123 }
124
125 fn resolve_coercion<V: AsVertex<Self::Vertex> + 'a>(
126 &self,
127 contexts: ContextIterator<'a, V>,
128 _type_name: &Arc<str>,
129 coerce_to_type: &Arc<str>,
130 _resolve_info: &ResolveInfo,
131 ) -> ContextOutcomeIterator<'a, V, bool> {
132 resolve_coercion_using_schema(contexts, Self::schema(), coerce_to_type.as_ref())
133 }
134}