grafbase_sdk/types/
selection_set.rs1use crate::{
2 SdkError,
3 types::{FieldDefinition, SubgraphSchema},
4 wit,
5};
6use serde::{Deserialize, de::DeserializeSeed};
7
8use super::DefinitionId;
9
10#[derive(Clone, Copy)]
12pub struct Field<'a> {
13 pub(crate) fields: &'a [wit::Field],
14 pub(crate) field: &'a wit::Field,
15}
16
17impl<'a> Field<'a> {
18 pub fn alias(&self) -> Option<&'a str> {
20 self.field.alias.as_deref()
21 }
22
23 pub fn arguments_id(&self) -> Option<ArgumentsId> {
25 self.field.arguments.map(ArgumentsId)
26 }
27
28 pub fn definition<'s>(&self, schema: &'s SubgraphSchema) -> FieldDefinition<'s> {
30 schema
31 .field_definition(self.definition_id())
32 .expect("Field definition not found, the wrong subgraph may have been used.")
33 }
34
35 pub fn definition_id(&self) -> DefinitionId {
37 DefinitionId(self.field.definition_id)
38 }
39
40 pub fn arguments<'de, T>(&self, variables: &'de Variables) -> Result<T, SdkError>
42 where
43 T: Deserialize<'de>,
44 {
45 match self.field.arguments {
46 Some(id) => variables.get(id.into()),
47 None => Ok(T::deserialize(serde_json::json!({}))?),
48 }
49 }
50
51 pub fn arguments_seed<'de, Seed>(&self, variables: &'de Variables, seed: Seed) -> Result<Seed::Value, SdkError>
53 where
54 Seed: DeserializeSeed<'de>,
55 {
56 match self.field.arguments {
57 Some(id) => variables.get_seed(id.into(), seed),
58 None => Ok(seed.deserialize(serde_json::json!({}))?),
59 }
60 }
61
62 pub fn selection_set(&self) -> SelectionSet<'a> {
64 self.field
65 .selection_set
66 .map(|selection_set| SelectionSet {
67 fields: self.fields,
68 selection_set,
69 })
70 .unwrap_or_else(|| SelectionSet {
71 fields: &[],
72 selection_set: wit::SelectionSet {
73 fields_ordered_by_parent_entity: (0, 0),
74 requires_typename: false,
75 },
76 })
77 }
78}
79
80#[derive(Clone, Copy)]
84pub struct SelectionSet<'a> {
85 fields: &'a [wit::Field],
86 selection_set: wit::SelectionSet,
87}
88
89impl<'a> SelectionSet<'a> {
90 pub fn is_empty(&self) -> bool {
92 self.fields().len() == 0
93 }
94
95 pub fn fields(&self) -> impl ExactSizeIterator<Item = Field<'a>> + 'a {
98 self.fields_ordered_by_parent_entity()
99 }
100
101 pub fn fields_ordered_by_parent_entity(&self) -> impl ExactSizeIterator<Item = Field<'a>> + 'a {
105 let (start, end) = self.selection_set.fields_ordered_by_parent_entity;
106 let fields = self.fields;
107 fields[usize::from(start)..usize::from(end)]
108 .iter()
109 .map(move |field| Field { fields, field })
110 }
111
112 pub fn requires_typename(&self) -> bool {
116 self.selection_set.requires_typename
117 }
118}
119
120#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
122pub struct ArgumentsId(wit::ArgumentsId);
123
124impl From<wit::ArgumentsId> for ArgumentsId {
125 fn from(id: wit::ArgumentsId) -> Self {
126 Self(id)
127 }
128}
129
130pub struct Variables(Vec<(wit::ArgumentsId, Vec<u8>)>);
132
133impl std::fmt::Debug for Variables {
134 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
135 f.debug_struct("Variables").finish_non_exhaustive()
136 }
137}
138
139impl From<Vec<(wit::ArgumentsId, Vec<u8>)>> for Variables {
140 fn from(values: Vec<(wit::ArgumentsId, Vec<u8>)>) -> Self {
141 Self(values)
142 }
143}
144
145impl Variables {
146 pub fn get<'de, T>(&'de self, id: ArgumentsId) -> Result<T, SdkError>
148 where
149 T: Deserialize<'de>,
150 {
151 let bytes = self.get_bytes(id);
152 crate::cbor::from_slice(bytes).map_err(Into::into)
153 }
154
155 pub fn get_seed<'de, Seed>(&'de self, id: ArgumentsId, seed: Seed) -> Result<Seed::Value, SdkError>
157 where
158 Seed: DeserializeSeed<'de>,
159 {
160 let bytes = self.get_bytes(id);
161 crate::cbor::from_slice_with_seed(bytes, seed).map_err(Into::into)
162 }
163
164 fn get_bytes(&self, id: ArgumentsId) -> &[u8] {
165 self.0
166 .iter()
167 .find_map(|(args_id, args)| if *args_id == id.0 { Some(args.as_slice()) } else { None })
168 .unwrap()
169 }
170}