1use fxhash::FxBuildHasher;
2use serde::Deserialize;
3use std::collections::HashMap;
4use std::fmt;
5
6use crate::{SdkError, cbor, wit};
7
8#[derive(Clone)]
9pub(crate) struct IndexedSchema {
10 name: String,
11 directives: Vec<wit::Directive>,
12 type_definitions: HashMap<DefinitionId, wit::TypeDefinition, FxBuildHasher>,
13 field_definitions: HashMap<DefinitionId, wit::FieldDefinition, FxBuildHasher>,
14 root_types: wit::RootTypes,
15}
16
17impl From<(String, wit::Schema)> for IndexedSchema {
18 fn from((name, schema): (String, wit::Schema)) -> Self {
19 Self {
20 name,
21 directives: schema.directives,
22 type_definitions: schema
23 .type_definitions
24 .into_iter()
25 .map(|def| {
26 let id = match &def {
27 wit::TypeDefinition::Scalar(scalar) => DefinitionId(scalar.id),
28 wit::TypeDefinition::Object(object) => DefinitionId(object.id),
29 wit::TypeDefinition::Interface(interface) => DefinitionId(interface.id),
30 wit::TypeDefinition::Union(union) => DefinitionId(union.id),
31 wit::TypeDefinition::Enum(enum_def) => DefinitionId(enum_def.id),
32 wit::TypeDefinition::InputObject(input_object) => DefinitionId(input_object.id),
33 };
34 (id, def)
35 })
36 .collect(),
37 field_definitions: schema
38 .field_definitions
39 .into_iter()
40 .map(|def| {
41 let id = DefinitionId(def.id);
42 (id, def)
43 })
44 .collect(),
45 root_types: schema.root_types,
46 }
47 }
48}
49
50pub struct SubgraphSchema(pub(crate) IndexedSchema);
52
53impl fmt::Debug for SubgraphSchema {
54 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55 f.debug_struct("SubgraphSchema")
56 .field("name", &self.subgraph_name())
57 .field(
58 "type_definitions",
59 &format!("<{} type definitions>", self.type_definitions().len()),
60 )
61 .field("directives", &self.directives().collect::<Vec<_>>())
62 .finish_non_exhaustive()
63 }
64}
65
66impl SubgraphSchema {
67 pub fn subgraph_name(&self) -> &str {
69 &self.0.name
70 }
71
72 pub fn type_definitions(&self) -> impl ExactSizeIterator<Item = TypeDefinition<'_>> {
74 let schema = &self.0;
75 self.0.type_definitions.values().map(move |def| (schema, def).into())
76 }
77
78 pub fn iter_fields(&self) -> impl Iterator<Item = FieldDefinition<'_>> {
80 let schema = &self.0;
81 self.0
82 .field_definitions
83 .values()
84 .map(|definition| FieldDefinition { schema, definition })
85 }
86
87 pub fn field_definition(&self, id: DefinitionId) -> Option<FieldDefinition<'_>> {
89 let schema = &self.0;
90 self.0.field_definitions.get(&id).map(move |def| FieldDefinition {
91 schema,
92 definition: def,
93 })
94 }
95
96 pub fn type_definition(&self, id: DefinitionId) -> Option<TypeDefinition<'_>> {
98 let schema = &self.0;
99 self.0.type_definitions.get(&id).map(move |def| (schema, def).into())
100 }
101
102 pub fn directives(&self) -> impl ExactSizeIterator<Item = Directive<'_>> {
104 self.0.directives.iter().map(Into::into)
105 }
106
107 pub fn query(&self) -> Option<ObjectDefinition<'_>> {
110 self.0.root_types.query_id.map(|id| {
111 let Some(wit::TypeDefinition::Object(def)) = self.0.type_definitions.get(&DefinitionId(id)) else {
112 unreachable!("Inconsitent schema");
113 };
114 (&self.0, def).into()
115 })
116 }
117
118 pub fn mutation(&self) -> Option<ObjectDefinition<'_>> {
120 self.0.root_types.mutation_id.map(|id| {
121 let Some(wit::TypeDefinition::Object(def)) = self.0.type_definitions.get(&DefinitionId(id)) else {
122 unreachable!("Inconsitent schema");
123 };
124 (&self.0, def).into()
125 })
126 }
127
128 pub fn subscription(&self) -> Option<ObjectDefinition<'_>> {
130 self.0.root_types.subscription_id.map(|id| {
131 let Some(wit::TypeDefinition::Object(def)) = self.0.type_definitions.get(&DefinitionId(id)) else {
132 unreachable!("Inconsitent schema");
133 };
134 (&self.0, def).into()
135 })
136 }
137}
138
139#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, serde::Serialize, serde::Deserialize)]
148pub struct DefinitionId(pub(crate) u32);
149
150impl From<DefinitionId> for u32 {
151 fn from(id: DefinitionId) -> u32 {
152 id.0
153 }
154}
155
156#[derive(Clone, Copy)]
158pub enum TypeDefinition<'a> {
159 Scalar(ScalarDefinition<'a>),
161 Object(ObjectDefinition<'a>),
163 Interface(InterfaceDefinition<'a>),
165 Union(UnionDefinition<'a>),
167 Enum(EnumDefinition<'a>),
169 InputObject(InputObjectDefinition<'a>),
171}
172
173impl fmt::Debug for TypeDefinition<'_> {
174 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
175 match self {
176 TypeDefinition::Scalar(def) => f.debug_tuple("Scalar").field(def).finish(),
177 TypeDefinition::Object(def) => f.debug_tuple("Object").field(def).finish(),
178 TypeDefinition::Interface(def) => f.debug_tuple("Interface").field(def).finish(),
179 TypeDefinition::Union(def) => f.debug_tuple("Union").field(def).finish(),
180 TypeDefinition::Enum(def) => f.debug_tuple("Enum").field(def).finish(),
181 TypeDefinition::InputObject(def) => f.debug_tuple("InputObject").field(def).finish(),
182 }
183 }
184}
185
186impl std::fmt::Display for TypeDefinition<'_> {
187 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result {
188 write!(f, "{}", self.name())
189 }
190}
191
192impl<'a> TypeDefinition<'a> {
193 pub fn id(&self) -> DefinitionId {
195 match self {
196 TypeDefinition::Scalar(def) => def.id(),
197 TypeDefinition::Object(def) => def.id(),
198 TypeDefinition::Interface(def) => def.id(),
199 TypeDefinition::Union(def) => def.id(),
200 TypeDefinition::Enum(def) => def.id(),
201 TypeDefinition::InputObject(def) => def.id(),
202 }
203 }
204
205 pub fn name(&self) -> &'a str {
207 match self {
208 TypeDefinition::Scalar(def) => def.name(),
209 TypeDefinition::Object(def) => def.name(),
210 TypeDefinition::Interface(def) => def.name(),
211 TypeDefinition::Union(def) => def.name(),
212 TypeDefinition::Enum(def) => def.name(),
213 TypeDefinition::InputObject(def) => def.name(),
214 }
215 }
216}
217
218impl<'a> From<(&'a IndexedSchema, &'a wit::TypeDefinition)> for TypeDefinition<'a> {
219 fn from((schema, definition): (&'a IndexedSchema, &'a wit::TypeDefinition)) -> Self {
220 match definition {
221 wit::TypeDefinition::Scalar(scalar) => TypeDefinition::Scalar((schema, scalar).into()),
222 wit::TypeDefinition::Object(object) => TypeDefinition::Object((schema, object).into()),
223 wit::TypeDefinition::Interface(interface) => TypeDefinition::Interface((schema, interface).into()),
224 wit::TypeDefinition::Union(union) => TypeDefinition::Union((schema, union).into()),
225 wit::TypeDefinition::Enum(enum_def) => TypeDefinition::Enum((schema, enum_def).into()),
226 wit::TypeDefinition::InputObject(input_object) => {
227 TypeDefinition::InputObject((schema, input_object).into())
228 }
229 }
230 }
231}
232
233#[derive(Clone, Copy)]
235pub struct ScalarDefinition<'a> {
236 pub(crate) definition: &'a wit::ScalarDefinition,
237}
238
239impl fmt::Debug for ScalarDefinition<'_> {
240 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
241 f.debug_struct("ScalarDefinition")
242 .field("id", &self.id())
243 .field("name", &self.name())
244 .field("specified_by_url", &self.specified_by_url())
245 .field("directives", &self.directives().collect::<Vec<_>>())
246 .finish()
247 }
248}
249
250impl std::fmt::Display for ScalarDefinition<'_> {
251 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result {
252 write!(f, "{}", self.name())
253 }
254}
255
256impl<'a> From<(&'a IndexedSchema, &'a wit::ScalarDefinition)> for ScalarDefinition<'a> {
257 fn from((_, definition): (&'a IndexedSchema, &'a wit::ScalarDefinition)) -> Self {
258 Self { definition }
259 }
260}
261
262impl<'a> ScalarDefinition<'a> {
263 pub fn id(&self) -> DefinitionId {
265 DefinitionId(self.definition.id)
266 }
267
268 pub fn name(&self) -> &'a str {
270 self.definition.name.as_str()
271 }
272
273 pub fn specified_by_url(&self) -> Option<&'a str> {
278 self.definition.specified_by_url.as_deref()
279 }
280
281 pub fn directives(&self) -> impl ExactSizeIterator<Item = Directive<'a>> + 'a {
283 self.definition.directives.iter().map(Into::into)
284 }
285}
286
287#[derive(Clone, Copy)]
289pub struct ObjectDefinition<'a> {
290 pub(crate) schema: &'a IndexedSchema,
291 pub(crate) definition: &'a wit::ObjectDefinition,
292}
293
294impl fmt::Debug for ObjectDefinition<'_> {
295 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
296 f.debug_struct("ObjectDefinition")
297 .field("id", &self.id())
298 .field("name", &self.name())
299 .field("fields", &self.fields().collect::<Vec<_>>())
300 .field(
301 "interfaces",
302 &self.interfaces().map(|inf| inf.name()).collect::<Vec<_>>(),
303 )
304 .field("directives", &self.directives().collect::<Vec<_>>())
305 .finish()
306 }
307}
308
309impl std::fmt::Display for ObjectDefinition<'_> {
310 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result {
311 write!(f, "{}", self.name())
312 }
313}
314
315impl<'a> From<(&'a IndexedSchema, &'a wit::ObjectDefinition)> for ObjectDefinition<'a> {
316 fn from((schema, definition): (&'a IndexedSchema, &'a wit::ObjectDefinition)) -> Self {
317 Self { schema, definition }
318 }
319}
320
321impl<'a> ObjectDefinition<'a> {
322 pub fn id(&self) -> DefinitionId {
324 DefinitionId(self.definition.id)
325 }
326
327 pub fn name(&self) -> &'a str {
329 self.definition.name.as_str()
330 }
331
332 pub fn fields(&self) -> impl ExactSizeIterator<Item = FieldDefinition<'a>> + 'a {
334 let schema = self.schema;
335 self.definition.field_ids.iter().map(move |id| FieldDefinition {
336 schema,
337 definition: &schema.field_definitions[&DefinitionId(*id)],
338 })
339 }
340
341 pub fn interfaces(&self) -> impl ExactSizeIterator<Item = InterfaceDefinition<'a>> + 'a {
343 let schema = self.schema;
344 self.definition.interface_ids.iter().map(move |&id| {
345 let Some(wit::TypeDefinition::Interface(def)) = &schema.type_definitions.get(&DefinitionId(id)) else {
346 unreachable!("Inconsitent schema");
347 };
348 (schema, def).into()
349 })
350 }
351
352 pub fn directives(&self) -> impl ExactSizeIterator<Item = Directive<'a>> + 'a {
354 self.definition.directives.iter().map(Into::into)
355 }
356}
357
358#[derive(Clone, Copy)]
363pub struct InterfaceDefinition<'a> {
364 pub(crate) schema: &'a IndexedSchema,
365 pub(crate) definition: &'a wit::InterfaceDefinition,
366}
367
368impl fmt::Debug for InterfaceDefinition<'_> {
369 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
370 f.debug_struct("InterfaceDefinition")
371 .field("id", &self.id())
372 .field("name", &self.name())
373 .field("fields", &self.fields().collect::<Vec<_>>())
374 .field(
375 "interfaces",
376 &self.interfaces().map(|inf| inf.name()).collect::<Vec<_>>(),
377 )
378 .field("directives", &self.directives().collect::<Vec<_>>())
379 .finish()
380 }
381}
382
383impl std::fmt::Display for InterfaceDefinition<'_> {
384 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result {
385 write!(f, "{}", self.name())
386 }
387}
388
389impl<'a> From<(&'a IndexedSchema, &'a wit::InterfaceDefinition)> for InterfaceDefinition<'a> {
390 fn from((schema, definition): (&'a IndexedSchema, &'a wit::InterfaceDefinition)) -> Self {
391 Self { schema, definition }
392 }
393}
394
395impl<'a> InterfaceDefinition<'a> {
396 pub fn id(&self) -> DefinitionId {
398 DefinitionId(self.definition.id)
399 }
400
401 pub fn name(&self) -> &'a str {
403 self.definition.name.as_str()
404 }
405
406 pub fn fields(&self) -> impl ExactSizeIterator<Item = FieldDefinition<'a>> + 'a {
408 let schema = self.schema;
409 self.definition.field_ids.iter().map(move |id| FieldDefinition {
410 definition: &schema.field_definitions[&DefinitionId(*id)],
411 schema,
412 })
413 }
414
415 pub fn interfaces(&self) -> impl ExactSizeIterator<Item = InterfaceDefinition<'a>> + 'a {
417 let schema = self.schema;
418 self.definition.interface_ids.iter().map(move |&id| {
419 let Some(wit::TypeDefinition::Interface(def)) = &schema.type_definitions.get(&DefinitionId(id)) else {
420 unreachable!("Inconsitent schema");
421 };
422 (schema, def).into()
423 })
424 }
425
426 pub fn directives(&self) -> impl ExactSizeIterator<Item = Directive<'a>> + 'a {
428 self.definition.directives.iter().map(Into::into)
429 }
430}
431
432#[derive(Clone, Copy)]
435pub enum EntityDefinition<'a> {
436 Object(ObjectDefinition<'a>),
438 Interface(InterfaceDefinition<'a>),
440}
441
442impl fmt::Debug for EntityDefinition<'_> {
443 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
444 match self {
445 EntityDefinition::Object(def) => f.debug_tuple("Object").field(def).finish(),
446 EntityDefinition::Interface(def) => f.debug_tuple("Interface").field(def).finish(),
447 }
448 }
449}
450
451impl std::fmt::Display for EntityDefinition<'_> {
452 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result {
453 match self {
454 EntityDefinition::Object(def) => write!(f, "{}", def.name()),
455 EntityDefinition::Interface(def) => write!(f, "{}", def.name()),
456 }
457 }
458}
459
460#[derive(Clone, Copy)]
464pub struct UnionDefinition<'a> {
465 pub(crate) schema: &'a IndexedSchema,
466 pub(crate) definition: &'a wit::UnionDefinition,
467}
468
469impl fmt::Debug for UnionDefinition<'_> {
470 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
471 f.debug_struct("UnionDefinition")
472 .field("id", &self.id())
473 .field("name", &self.name())
474 .field(
475 "member_types",
476 &self.member_types().map(|obj| obj.name()).collect::<Vec<_>>(),
477 )
478 .field("directives", &self.directives().collect::<Vec<_>>())
479 .finish()
480 }
481}
482
483impl std::fmt::Display for UnionDefinition<'_> {
484 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result {
485 write!(f, "{}", self.name())
486 }
487}
488
489impl<'a> From<(&'a IndexedSchema, &'a wit::UnionDefinition)> for UnionDefinition<'a> {
490 fn from((schema, definition): (&'a IndexedSchema, &'a wit::UnionDefinition)) -> Self {
491 Self { schema, definition }
492 }
493}
494
495impl<'a> UnionDefinition<'a> {
496 pub fn id(&self) -> DefinitionId {
498 DefinitionId(self.definition.id)
499 }
500
501 pub fn name(&self) -> &'a str {
503 self.definition.name.as_str()
504 }
505
506 pub fn member_types(&self) -> impl ExactSizeIterator<Item = ObjectDefinition<'a>> + 'a {
508 let schema = self.schema;
509 self.definition.member_types.iter().map(move |&id| {
510 let Some(wit::TypeDefinition::Object(def)) = &schema.type_definitions.get(&DefinitionId(id)) else {
511 unreachable!("Inconsitent schema");
512 };
513 (schema, def).into()
514 })
515 }
516
517 pub fn directives(&self) -> impl ExactSizeIterator<Item = Directive<'a>> + 'a {
519 self.definition.directives.iter().map(Into::into)
520 }
521}
522
523#[derive(Clone, Copy)]
527pub struct EnumDefinition<'a> {
528 pub(crate) definition: &'a wit::EnumDefinition,
529}
530
531impl fmt::Debug for EnumDefinition<'_> {
532 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
533 f.debug_struct("EnumDefinition")
534 .field("id", &self.id())
535 .field("name", &self.name())
536 .field("values", &self.values().collect::<Vec<_>>())
537 .field("directives", &self.directives().collect::<Vec<_>>())
538 .finish()
539 }
540}
541
542impl std::fmt::Display for EnumDefinition<'_> {
543 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
544 write!(f, "{}", self.name())
545 }
546}
547
548impl<'a> From<(&'a IndexedSchema, &'a wit::EnumDefinition)> for EnumDefinition<'a> {
549 fn from((_, definition): (&'a IndexedSchema, &'a wit::EnumDefinition)) -> Self {
550 Self { definition }
551 }
552}
553
554impl<'a> EnumDefinition<'a> {
555 pub fn id(&self) -> DefinitionId {
557 DefinitionId(self.definition.id)
558 }
559
560 pub fn name(&self) -> &'a str {
562 self.definition.name.as_str()
563 }
564
565 pub fn values(&self) -> impl ExactSizeIterator<Item = EnumValue<'a>> + 'a {
567 self.definition.values.iter().map(Into::into)
568 }
569
570 pub fn directives(&self) -> impl ExactSizeIterator<Item = Directive<'a>> + 'a {
572 self.definition.directives.iter().map(Into::into)
573 }
574}
575
576#[derive(Clone, Copy)]
581pub struct InputObjectDefinition<'a> {
582 pub(crate) schema: &'a IndexedSchema,
583 pub(crate) definition: &'a wit::InputObjectDefinition,
584}
585
586impl fmt::Debug for InputObjectDefinition<'_> {
587 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
588 f.debug_struct("InputObjectDefinition")
589 .field("id", &self.id())
590 .field("name", &self.name())
591 .field("input_fields", &self.input_fields().collect::<Vec<_>>())
592 .field("directives", &self.directives().collect::<Vec<_>>())
593 .finish()
594 }
595}
596
597impl std::fmt::Display for InputObjectDefinition<'_> {
598 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result {
599 write!(f, "{}", self.name())
600 }
601}
602
603impl<'a> From<(&'a IndexedSchema, &'a wit::InputObjectDefinition)> for InputObjectDefinition<'a> {
604 fn from((schema, definition): (&'a IndexedSchema, &'a wit::InputObjectDefinition)) -> Self {
605 Self { schema, definition }
606 }
607}
608
609impl<'a> InputObjectDefinition<'a> {
610 pub fn id(&self) -> DefinitionId {
612 DefinitionId(self.definition.id)
613 }
614
615 pub fn name(&self) -> &'a str {
617 self.definition.name.as_str()
618 }
619
620 pub fn input_fields(&self) -> impl ExactSizeIterator<Item = InputValueDefinition<'a>> + 'a {
622 self.definition.input_fields.iter().map(|field| InputValueDefinition {
623 definition: field,
624 schema: self.schema,
625 })
626 }
627
628 pub fn directives(&self) -> impl ExactSizeIterator<Item = Directive<'a>> + 'a {
630 self.definition.directives.iter().map(Into::into)
631 }
632}
633
634#[derive(Clone, Copy)]
639pub struct FieldDefinition<'a> {
640 pub(crate) schema: &'a IndexedSchema,
641 pub(crate) definition: &'a wit::FieldDefinition,
642}
643
644impl fmt::Debug for FieldDefinition<'_> {
645 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
646 f.debug_struct("FieldDefinition")
647 .field("id", &self.id())
648 .field("name", &self.name())
649 .field("type", &self.ty())
650 .field("arguments", &self.arguments().collect::<Vec<_>>())
651 .field("directives", &self.directives().collect::<Vec<_>>())
652 .finish()
653 }
654}
655
656impl std::fmt::Display for FieldDefinition<'_> {
657 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
658 write!(f, "{}.{}", self.parent_entity(), self.name())
659 }
660}
661
662impl<'a> FieldDefinition<'a> {
663 pub fn id(&self) -> DefinitionId {
665 DefinitionId(self.definition.id)
666 }
667
668 pub fn name(&self) -> &'a str {
670 self.definition.name.as_str()
671 }
672
673 pub fn parent_entity(&self) -> EntityDefinition<'a> {
675 let def = &self.schema.type_definitions[&DefinitionId(self.definition.parent_type_id)];
676 match def {
677 wit::TypeDefinition::Object(obj) => EntityDefinition::Object((self.schema, obj).into()),
678 wit::TypeDefinition::Interface(inf) => EntityDefinition::Interface((self.schema, inf).into()),
679 _ => unreachable!("Field definition parent type must be an object or interface"),
680 }
681 }
682
683 pub fn ty(&self) -> Type<'a> {
685 (self.schema, &self.definition.ty).into()
686 }
687
688 pub fn arguments(&self) -> impl ExactSizeIterator<Item = InputValueDefinition<'a>> + 'a {
690 self.definition.arguments.iter().map(|arg| InputValueDefinition {
691 definition: arg,
692 schema: self.schema,
693 })
694 }
695
696 pub fn directives(&self) -> impl ExactSizeIterator<Item = Directive<'a>> + 'a {
698 self.definition.directives.iter().map(Into::into)
699 }
700}
701
702#[derive(Clone, Copy)]
707pub struct Type<'a> {
708 schema: &'a IndexedSchema,
709 ty: &'a wit::Ty,
710}
711
712impl fmt::Debug for Type<'_> {
713 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
714 f.debug_struct("Type")
715 .field("definition", &self.definition().name())
716 .field("wrapping", &self.wrapping().collect::<Vec<_>>())
717 .finish()
718 }
719}
720
721impl<'a> From<(&'a IndexedSchema, &'a wit::Ty)> for Type<'a> {
722 fn from((schema, ty): (&'a IndexedSchema, &'a wit::Ty)) -> Self {
723 Self { schema, ty }
724 }
725}
726
727impl<'a> Type<'a> {
728 pub fn is_non_null(&self) -> bool {
730 self.wrapping().last() == Some(WrappingType::NonNull)
731 }
732
733 pub fn is_list(&self) -> bool {
735 self.wrapping().any(|w| matches!(w, WrappingType::List))
736 }
737
738 pub fn wrapping(&self) -> impl ExactSizeIterator<Item = WrappingType> + 'a {
741 self.ty.wrapping.iter().map(|&w| w.into())
742 }
743
744 pub fn definition(&self) -> TypeDefinition<'a> {
746 let Some(def) = self.schema.type_definitions.get(&DefinitionId(self.ty.definition_id)) else {
747 unreachable!("Inconsitent schema");
748 };
749 (self.schema, def).into()
750 }
751}
752
753#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
758pub enum WrappingType {
759 NonNull,
761 List,
763}
764
765impl From<wit::WrappingType> for WrappingType {
766 fn from(wrapping: wit::WrappingType) -> Self {
767 match wrapping {
768 wit::WrappingType::NonNull => WrappingType::NonNull,
769 wit::WrappingType::List => WrappingType::List,
770 }
771 }
772}
773
774#[derive(Clone, Copy)]
778pub struct InputValueDefinition<'a> {
779 pub(crate) schema: &'a IndexedSchema,
780 pub(crate) definition: &'a wit::InputValueDefinition,
781}
782
783impl fmt::Debug for InputValueDefinition<'_> {
784 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
785 f.debug_struct("InputValueDefinition")
786 .field("id", &self.id())
787 .field("name", &self.name())
788 .field("type", &self.ty())
789 .field("directives", &self.directives().collect::<Vec<_>>())
790 .finish()
791 }
792}
793
794impl<'a> From<(&'a IndexedSchema, &'a wit::InputValueDefinition)> for InputValueDefinition<'a> {
795 fn from((schema, definition): (&'a IndexedSchema, &'a wit::InputValueDefinition)) -> Self {
796 Self { schema, definition }
797 }
798}
799
800impl<'a> InputValueDefinition<'a> {
801 pub fn id(&self) -> DefinitionId {
803 DefinitionId(self.definition.id)
804 }
805
806 pub fn name(&self) -> &'a str {
808 self.definition.name.as_str()
809 }
810
811 pub fn ty(&self) -> Type<'a> {
813 (self.schema, &self.definition.ty).into()
814 }
815
816 pub fn directives(&self) -> impl ExactSizeIterator<Item = Directive<'a>> + 'a {
818 self.definition.directives.iter().map(Into::into)
819 }
820}
821
822#[derive(Clone, Copy)]
824pub struct EnumValue<'a>(&'a wit::EnumValue);
825
826impl fmt::Debug for EnumValue<'_> {
827 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
828 f.debug_struct("EnumValue")
829 .field("name", &self.name())
830 .field("directives", &self.directives().collect::<Vec<_>>())
831 .finish()
832 }
833}
834
835impl<'a> From<&'a wit::EnumValue> for EnumValue<'a> {
836 fn from(enum_value: &'a wit::EnumValue) -> Self {
837 Self(enum_value)
838 }
839}
840
841impl<'a> EnumValue<'a> {
842 pub fn name(&self) -> &'a str {
844 self.0.name.as_str()
845 }
846
847 pub fn directives(&self) -> impl ExactSizeIterator<Item = Directive<'a>> + 'a {
849 self.0.directives.iter().map(Into::into)
850 }
851}
852
853#[derive(Clone, Copy)]
858pub struct Directive<'a>(pub(crate) DirectiveInner<'a>);
859
860#[derive(Clone, Copy)]
862pub(crate) enum DirectiveInner<'a> {
863 Wit(&'a wit::Directive),
864 NameAndArgs { name: &'a str, arguments: &'a [u8] },
865}
866
867impl fmt::Debug for Directive<'_> {
868 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
869 f.debug_struct("Directive")
870 .field("name", &self.name())
871 .field("arguments", &"<binary arguments>")
872 .finish()
873 }
874}
875
876impl<'a> From<&'a wit::Directive> for Directive<'a> {
877 fn from(directive: &'a wit::Directive) -> Self {
878 Self(DirectiveInner::Wit(directive))
879 }
880}
881
882impl<'a> Directive<'a> {
883 pub fn name(&self) -> &'a str {
885 match &self.0 {
886 DirectiveInner::Wit(directive) => directive.name.as_str(),
887 DirectiveInner::NameAndArgs { name, .. } => name,
888 }
889 }
890
891 pub fn arguments<T>(&self) -> Result<T, SdkError>
893 where
894 T: Deserialize<'a>,
895 {
896 cbor::from_slice::<T>(self.arguments_bytes()).map_err(Into::into)
897 }
898
899 #[inline]
901 pub fn arguments_seed<T>(&self, seed: T) -> Result<T::Value, SdkError>
902 where
903 T: serde::de::DeserializeSeed<'a>,
904 {
905 cbor::from_slice_with_seed(self.arguments_bytes(), seed).map_err(Into::into)
906 }
907
908 fn arguments_bytes(&self) -> &'a [u8] {
909 match &self.0 {
910 DirectiveInner::Wit(directive) => &directive.arguments,
911 DirectiveInner::NameAndArgs { arguments, .. } => arguments,
912 }
913 }
914}