1use fxhash::FxHasher32;
2use serde::Deserialize;
3use std::collections::HashMap;
4use std::{fmt, hash::BuildHasherDefault};
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, BuildHasherDefault<FxHasher32>>,
13 root_types: wit::RootTypes,
14}
15
16impl From<(String, wit::Schema)> for IndexedSchema {
17 fn from((name, schema): (String, wit::Schema)) -> Self {
18 Self {
19 name,
20 directives: schema.directives,
21 type_definitions: schema
22 .type_definitions
23 .into_iter()
24 .map(|def| {
25 let id = match &def {
26 wit::TypeDefinition::Scalar(scalar) => DefinitionId(scalar.id),
27 wit::TypeDefinition::Object(object) => DefinitionId(object.id),
28 wit::TypeDefinition::Interface(interface) => DefinitionId(interface.id),
29 wit::TypeDefinition::Union(union) => DefinitionId(union.id),
30 wit::TypeDefinition::Enum(enum_def) => DefinitionId(enum_def.id),
31 wit::TypeDefinition::InputObject(input_object) => DefinitionId(input_object.id),
32 };
33 (id, def)
34 })
35 .collect(),
36 root_types: schema.root_types,
37 }
38 }
39}
40
41pub struct SubgraphSchema<'a>(pub(crate) &'a IndexedSchema);
43
44impl fmt::Debug for SubgraphSchema<'_> {
45 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46 f.debug_struct("SubgraphSchema")
47 .field("name", &self.subgraph_name())
48 .field(
49 "type_definitions",
50 &format!("<{} type definitions>", self.type_definitions().len()),
51 )
52 .field("directives", &self.directives().collect::<Vec<_>>())
53 .finish_non_exhaustive()
54 }
55}
56
57impl<'a> SubgraphSchema<'a> {
58 pub fn subgraph_name(&self) -> &'a str {
60 &self.0.name
61 }
62
63 pub fn type_definitions(&self) -> impl ExactSizeIterator<Item = TypeDefinition<'a>> + 'a {
65 let schema = self.0;
66 self.0.type_definitions.values().map(move |def| (schema, def).into())
67 }
68
69 pub fn iter_fields(&self) -> impl Iterator<Item = FieldDefinition<'a>> + 'a {
71 let schema = self.0;
72 self.0
73 .type_definitions
74 .values()
75 .filter_map(move |def| match def {
76 wit::TypeDefinition::Object(obj) => Some((EntityDefinition::Object((schema, obj).into()), &obj.fields)),
77 wit::TypeDefinition::Interface(inf) => {
78 Some((EntityDefinition::Interface((schema, inf).into()), &inf.fields))
79 }
80 _ => None,
81 })
82 .flat_map(move |(parent_entity, fields)| {
83 fields.iter().map(move |definition| FieldDefinition {
84 definition,
85 parent_entity,
86 schema,
87 })
88 })
89 }
90
91 pub fn type_definition(&self, id: &DefinitionId) -> Option<TypeDefinition<'a>> {
93 let schema = self.0;
94 self.0.type_definitions.get(id).map(move |def| (schema, def).into())
95 }
96
97 pub fn directives(&self) -> impl ExactSizeIterator<Item = Directive<'a>> + 'a {
99 self.0.directives.iter().map(Into::into)
100 }
101
102 pub fn query(&self) -> Option<ObjectDefinition<'a>> {
105 self.0.root_types.query_id.map(|id| {
106 let Some(wit::TypeDefinition::Object(def)) = self.0.type_definitions.get(&DefinitionId(id)) else {
107 unreachable!("Inconsitent schema");
108 };
109 (self.0, def).into()
110 })
111 }
112
113 pub fn mutation(&self) -> Option<ObjectDefinition<'a>> {
115 self.0.root_types.mutation_id.map(|id| {
116 let Some(wit::TypeDefinition::Object(def)) = self.0.type_definitions.get(&DefinitionId(id)) else {
117 unreachable!("Inconsitent schema");
118 };
119 (self.0, def).into()
120 })
121 }
122
123 pub fn subscription(&self) -> Option<ObjectDefinition<'a>> {
125 self.0.root_types.subscription_id.map(|id| {
126 let Some(wit::TypeDefinition::Object(def)) = self.0.type_definitions.get(&DefinitionId(id)) else {
127 unreachable!("Inconsitent schema");
128 };
129 (self.0, def).into()
130 })
131 }
132}
133
134#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, serde::Serialize, serde::Deserialize)]
143pub struct DefinitionId(pub(crate) u32);
144
145impl From<DefinitionId> for u32 {
146 fn from(id: DefinitionId) -> u32 {
147 id.0
148 }
149}
150
151#[derive(Clone, Copy)]
153pub enum TypeDefinition<'a> {
154 Scalar(ScalarDefinition<'a>),
156 Object(ObjectDefinition<'a>),
158 Interface(InterfaceDefinition<'a>),
160 Union(UnionDefinition<'a>),
162 Enum(EnumDefinition<'a>),
164 InputObject(InputObjectDefinition<'a>),
166}
167
168impl fmt::Debug for TypeDefinition<'_> {
169 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
170 match self {
171 TypeDefinition::Scalar(def) => f.debug_tuple("Scalar").field(def).finish(),
172 TypeDefinition::Object(def) => f.debug_tuple("Object").field(def).finish(),
173 TypeDefinition::Interface(def) => f.debug_tuple("Interface").field(def).finish(),
174 TypeDefinition::Union(def) => f.debug_tuple("Union").field(def).finish(),
175 TypeDefinition::Enum(def) => f.debug_tuple("Enum").field(def).finish(),
176 TypeDefinition::InputObject(def) => f.debug_tuple("InputObject").field(def).finish(),
177 }
178 }
179}
180
181impl std::fmt::Display for TypeDefinition<'_> {
182 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result {
183 write!(f, "{}", self.name())
184 }
185}
186
187impl<'a> TypeDefinition<'a> {
188 pub fn id(&self) -> DefinitionId {
190 match self {
191 TypeDefinition::Scalar(def) => def.id(),
192 TypeDefinition::Object(def) => def.id(),
193 TypeDefinition::Interface(def) => def.id(),
194 TypeDefinition::Union(def) => def.id(),
195 TypeDefinition::Enum(def) => def.id(),
196 TypeDefinition::InputObject(def) => def.id(),
197 }
198 }
199
200 pub fn name(&self) -> &'a str {
202 match self {
203 TypeDefinition::Scalar(def) => def.name(),
204 TypeDefinition::Object(def) => def.name(),
205 TypeDefinition::Interface(def) => def.name(),
206 TypeDefinition::Union(def) => def.name(),
207 TypeDefinition::Enum(def) => def.name(),
208 TypeDefinition::InputObject(def) => def.name(),
209 }
210 }
211}
212
213impl<'a> From<(&'a IndexedSchema, &'a wit::TypeDefinition)> for TypeDefinition<'a> {
214 fn from((schema, definition): (&'a IndexedSchema, &'a wit::TypeDefinition)) -> Self {
215 match definition {
216 wit::TypeDefinition::Scalar(scalar) => TypeDefinition::Scalar((schema, scalar).into()),
217 wit::TypeDefinition::Object(object) => TypeDefinition::Object((schema, object).into()),
218 wit::TypeDefinition::Interface(interface) => TypeDefinition::Interface((schema, interface).into()),
219 wit::TypeDefinition::Union(union) => TypeDefinition::Union((schema, union).into()),
220 wit::TypeDefinition::Enum(enum_def) => TypeDefinition::Enum((schema, enum_def).into()),
221 wit::TypeDefinition::InputObject(input_object) => {
222 TypeDefinition::InputObject((schema, input_object).into())
223 }
224 }
225 }
226}
227
228#[derive(Clone, Copy)]
230pub struct ScalarDefinition<'a> {
231 pub(crate) definition: &'a wit::ScalarDefinition,
232}
233
234impl fmt::Debug for ScalarDefinition<'_> {
235 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
236 f.debug_struct("ScalarDefinition")
237 .field("id", &self.id())
238 .field("name", &self.name())
239 .field("specified_by_url", &self.specified_by_url())
240 .field("directives", &self.directives().collect::<Vec<_>>())
241 .finish()
242 }
243}
244
245impl std::fmt::Display for ScalarDefinition<'_> {
246 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result {
247 write!(f, "{}", self.name())
248 }
249}
250
251impl<'a> From<(&'a IndexedSchema, &'a wit::ScalarDefinition)> for ScalarDefinition<'a> {
252 fn from((_, definition): (&'a IndexedSchema, &'a wit::ScalarDefinition)) -> Self {
253 Self { definition }
254 }
255}
256
257impl<'a> ScalarDefinition<'a> {
258 pub fn id(&self) -> DefinitionId {
260 DefinitionId(self.definition.id)
261 }
262
263 pub fn name(&self) -> &'a str {
265 self.definition.name.as_str()
266 }
267
268 pub fn specified_by_url(&self) -> Option<&'a str> {
273 self.definition.specified_by_url.as_deref()
274 }
275
276 pub fn directives(&self) -> impl ExactSizeIterator<Item = Directive<'a>> + 'a {
278 self.definition.directives.iter().map(Into::into)
279 }
280}
281
282#[derive(Clone, Copy)]
284pub struct ObjectDefinition<'a> {
285 pub(crate) schema: &'a IndexedSchema,
286 pub(crate) definition: &'a wit::ObjectDefinition,
287}
288
289impl fmt::Debug for ObjectDefinition<'_> {
290 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
291 f.debug_struct("ObjectDefinition")
292 .field("id", &self.id())
293 .field("name", &self.name())
294 .field("fields", &self.fields().collect::<Vec<_>>())
295 .field(
296 "interfaces",
297 &self.interfaces().map(|inf| inf.name()).collect::<Vec<_>>(),
298 )
299 .field("directives", &self.directives().collect::<Vec<_>>())
300 .finish()
301 }
302}
303
304impl std::fmt::Display for ObjectDefinition<'_> {
305 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result {
306 write!(f, "{}", self.name())
307 }
308}
309
310impl<'a> From<(&'a IndexedSchema, &'a wit::ObjectDefinition)> for ObjectDefinition<'a> {
311 fn from((schema, definition): (&'a IndexedSchema, &'a wit::ObjectDefinition)) -> Self {
312 Self { schema, definition }
313 }
314}
315
316impl<'a> ObjectDefinition<'a> {
317 pub fn id(&self) -> DefinitionId {
319 DefinitionId(self.definition.id)
320 }
321
322 pub fn name(&self) -> &'a str {
324 self.definition.name.as_str()
325 }
326
327 pub fn fields(&self) -> impl ExactSizeIterator<Item = FieldDefinition<'a>> + 'a {
329 let schema = self.schema;
330 let parent_entity = EntityDefinition::Object(*self);
331 self.definition.fields.iter().map(move |field| FieldDefinition {
332 schema,
333 parent_entity,
334 definition: field,
335 })
336 }
337
338 pub fn interfaces(&self) -> impl ExactSizeIterator<Item = InterfaceDefinition<'a>> + 'a {
340 let schema = self.schema;
341 self.definition.interfaces.iter().map(move |&id| {
342 let Some(wit::TypeDefinition::Interface(def)) = &schema.type_definitions.get(&DefinitionId(id)) else {
343 unreachable!("Inconsitent schema");
344 };
345 (schema, def).into()
346 })
347 }
348
349 pub fn directives(&self) -> impl ExactSizeIterator<Item = Directive<'a>> + 'a {
351 self.definition.directives.iter().map(Into::into)
352 }
353}
354
355#[derive(Clone, Copy)]
360pub struct InterfaceDefinition<'a> {
361 pub(crate) schema: &'a IndexedSchema,
362 pub(crate) definition: &'a wit::InterfaceDefinition,
363}
364
365impl fmt::Debug for InterfaceDefinition<'_> {
366 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
367 f.debug_struct("InterfaceDefinition")
368 .field("id", &self.id())
369 .field("name", &self.name())
370 .field("fields", &self.fields().collect::<Vec<_>>())
371 .field(
372 "interfaces",
373 &self.interfaces().map(|inf| inf.name()).collect::<Vec<_>>(),
374 )
375 .field("directives", &self.directives().collect::<Vec<_>>())
376 .finish()
377 }
378}
379
380impl std::fmt::Display for InterfaceDefinition<'_> {
381 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result {
382 write!(f, "{}", self.name())
383 }
384}
385
386impl<'a> From<(&'a IndexedSchema, &'a wit::InterfaceDefinition)> for InterfaceDefinition<'a> {
387 fn from((schema, definition): (&'a IndexedSchema, &'a wit::InterfaceDefinition)) -> Self {
388 Self { schema, definition }
389 }
390}
391
392impl<'a> InterfaceDefinition<'a> {
393 pub fn id(&self) -> DefinitionId {
395 DefinitionId(self.definition.id)
396 }
397
398 pub fn name(&self) -> &'a str {
400 self.definition.name.as_str()
401 }
402
403 pub fn fields(&self) -> impl ExactSizeIterator<Item = FieldDefinition<'a>> + 'a {
405 let schema = self.schema;
406 let parent_entity = EntityDefinition::Interface(*self);
407 self.definition.fields.iter().map(move |field| FieldDefinition {
408 definition: field,
409 parent_entity,
410 schema,
411 })
412 }
413
414 pub fn interfaces(&self) -> impl ExactSizeIterator<Item = InterfaceDefinition<'a>> + 'a {
416 let schema = self.schema;
417 self.definition.interfaces.iter().map(move |&id| {
418 let Some(wit::TypeDefinition::Interface(def)) = &schema.type_definitions.get(&DefinitionId(id)) else {
419 unreachable!("Inconsitent schema");
420 };
421 (schema, def).into()
422 })
423 }
424
425 pub fn directives(&self) -> impl ExactSizeIterator<Item = Directive<'a>> + 'a {
427 self.definition.directives.iter().map(Into::into)
428 }
429}
430
431#[derive(Clone, Copy)]
434pub enum EntityDefinition<'a> {
435 Object(ObjectDefinition<'a>),
437 Interface(InterfaceDefinition<'a>),
439}
440
441impl fmt::Debug for EntityDefinition<'_> {
442 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
443 match self {
444 EntityDefinition::Object(def) => f.debug_tuple("Object").field(def).finish(),
445 EntityDefinition::Interface(def) => f.debug_tuple("Interface").field(def).finish(),
446 }
447 }
448}
449
450impl std::fmt::Display for EntityDefinition<'_> {
451 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result {
452 match self {
453 EntityDefinition::Object(def) => write!(f, "{}", def.name()),
454 EntityDefinition::Interface(def) => write!(f, "{}", def.name()),
455 }
456 }
457}
458
459#[derive(Clone, Copy)]
463pub struct UnionDefinition<'a> {
464 pub(crate) schema: &'a IndexedSchema,
465 pub(crate) definition: &'a wit::UnionDefinition,
466}
467
468impl fmt::Debug for UnionDefinition<'_> {
469 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
470 f.debug_struct("UnionDefinition")
471 .field("id", &self.id())
472 .field("name", &self.name())
473 .field(
474 "member_types",
475 &self.member_types().map(|obj| obj.name()).collect::<Vec<_>>(),
476 )
477 .field("directives", &self.directives().collect::<Vec<_>>())
478 .finish()
479 }
480}
481
482impl std::fmt::Display for UnionDefinition<'_> {
483 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result {
484 write!(f, "{}", self.name())
485 }
486}
487
488impl<'a> From<(&'a IndexedSchema, &'a wit::UnionDefinition)> for UnionDefinition<'a> {
489 fn from((schema, definition): (&'a IndexedSchema, &'a wit::UnionDefinition)) -> Self {
490 Self { schema, definition }
491 }
492}
493
494impl<'a> UnionDefinition<'a> {
495 pub fn id(&self) -> DefinitionId {
497 DefinitionId(self.definition.id)
498 }
499
500 pub fn name(&self) -> &'a str {
502 self.definition.name.as_str()
503 }
504
505 pub fn member_types(&self) -> impl ExactSizeIterator<Item = ObjectDefinition<'a>> + 'a {
507 let schema = self.schema;
508 self.definition.member_types.iter().map(move |&id| {
509 let Some(wit::TypeDefinition::Object(def)) = &schema.type_definitions.get(&DefinitionId(id)) else {
510 unreachable!("Inconsitent schema");
511 };
512 (schema, def).into()
513 })
514 }
515
516 pub fn directives(&self) -> impl ExactSizeIterator<Item = Directive<'a>> + 'a {
518 self.definition.directives.iter().map(Into::into)
519 }
520}
521
522#[derive(Clone, Copy)]
526pub struct EnumDefinition<'a> {
527 pub(crate) definition: &'a wit::EnumDefinition,
528}
529
530impl fmt::Debug for EnumDefinition<'_> {
531 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
532 f.debug_struct("EnumDefinition")
533 .field("id", &self.id())
534 .field("name", &self.name())
535 .field("values", &self.values().collect::<Vec<_>>())
536 .field("directives", &self.directives().collect::<Vec<_>>())
537 .finish()
538 }
539}
540
541impl std::fmt::Display for EnumDefinition<'_> {
542 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
543 write!(f, "{}", self.name())
544 }
545}
546
547impl<'a> From<(&'a IndexedSchema, &'a wit::EnumDefinition)> for EnumDefinition<'a> {
548 fn from((_, definition): (&'a IndexedSchema, &'a wit::EnumDefinition)) -> Self {
549 Self { definition }
550 }
551}
552
553impl<'a> EnumDefinition<'a> {
554 pub fn id(&self) -> DefinitionId {
556 DefinitionId(self.definition.id)
557 }
558
559 pub fn name(&self) -> &'a str {
561 self.definition.name.as_str()
562 }
563
564 pub fn values(&self) -> impl ExactSizeIterator<Item = EnumValue<'a>> + 'a {
566 self.definition.values.iter().map(Into::into)
567 }
568
569 pub fn directives(&self) -> impl ExactSizeIterator<Item = Directive<'a>> + 'a {
571 self.definition.directives.iter().map(Into::into)
572 }
573}
574
575#[derive(Clone, Copy)]
580pub struct InputObjectDefinition<'a> {
581 pub(crate) schema: &'a IndexedSchema,
582 pub(crate) definition: &'a wit::InputObjectDefinition,
583}
584
585impl fmt::Debug for InputObjectDefinition<'_> {
586 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
587 f.debug_struct("InputObjectDefinition")
588 .field("id", &self.id())
589 .field("name", &self.name())
590 .field("input_fields", &self.input_fields().collect::<Vec<_>>())
591 .field("directives", &self.directives().collect::<Vec<_>>())
592 .finish()
593 }
594}
595
596impl std::fmt::Display for InputObjectDefinition<'_> {
597 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result {
598 write!(f, "{}", self.name())
599 }
600}
601
602impl<'a> From<(&'a IndexedSchema, &'a wit::InputObjectDefinition)> for InputObjectDefinition<'a> {
603 fn from((schema, definition): (&'a IndexedSchema, &'a wit::InputObjectDefinition)) -> Self {
604 Self { schema, definition }
605 }
606}
607
608impl<'a> InputObjectDefinition<'a> {
609 pub fn id(&self) -> DefinitionId {
611 DefinitionId(self.definition.id)
612 }
613
614 pub fn name(&self) -> &'a str {
616 self.definition.name.as_str()
617 }
618
619 pub fn input_fields(&self) -> impl ExactSizeIterator<Item = InputValueDefinition<'a>> + 'a {
621 self.definition.input_fields.iter().map(|field| InputValueDefinition {
622 definition: field,
623 schema: self.schema,
624 })
625 }
626
627 pub fn directives(&self) -> impl ExactSizeIterator<Item = Directive<'a>> + 'a {
629 self.definition.directives.iter().map(Into::into)
630 }
631}
632
633#[derive(Clone, Copy)]
638pub struct FieldDefinition<'a> {
639 pub(crate) schema: &'a IndexedSchema,
640 pub(crate) parent_entity: EntityDefinition<'a>,
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 self.parent_entity
676 }
677
678 pub fn ty(&self) -> Type<'a> {
680 (self.schema, &self.definition.ty).into()
681 }
682
683 pub fn arguments(&self) -> impl ExactSizeIterator<Item = InputValueDefinition<'a>> + 'a {
685 self.definition.arguments.iter().map(|arg| InputValueDefinition {
686 definition: arg,
687 schema: self.schema,
688 })
689 }
690
691 pub fn directives(&self) -> impl ExactSizeIterator<Item = Directive<'a>> + 'a {
693 self.definition.directives.iter().map(Into::into)
694 }
695}
696
697#[derive(Clone, Copy)]
702pub struct Type<'a> {
703 schema: &'a IndexedSchema,
704 ty: &'a wit::Ty,
705}
706
707impl fmt::Debug for Type<'_> {
708 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
709 f.debug_struct("Type")
710 .field("definition", &self.definition().name())
711 .field("wrapping", &self.wrapping().collect::<Vec<_>>())
712 .finish()
713 }
714}
715
716impl<'a> From<(&'a IndexedSchema, &'a wit::Ty)> for Type<'a> {
717 fn from((schema, ty): (&'a IndexedSchema, &'a wit::Ty)) -> Self {
718 Self { schema, ty }
719 }
720}
721
722impl<'a> Type<'a> {
723 pub fn is_non_null(&self) -> bool {
725 self.wrapping().last() == Some(WrappingType::NonNull)
726 }
727
728 pub fn is_list(&self) -> bool {
730 self.wrapping().any(|w| matches!(w, WrappingType::List))
731 }
732
733 pub fn wrapping(&self) -> impl ExactSizeIterator<Item = WrappingType> + 'a {
736 self.ty.wrapping.iter().map(|&w| w.into())
737 }
738
739 pub fn definition(&self) -> TypeDefinition<'a> {
741 let Some(def) = self.schema.type_definitions.get(&DefinitionId(self.ty.definition_id)) else {
742 unreachable!("Inconsitent schema");
743 };
744 (self.schema, def).into()
745 }
746}
747
748#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
753pub enum WrappingType {
754 NonNull,
756 List,
758}
759
760impl From<wit::WrappingType> for WrappingType {
761 fn from(wrapping: wit::WrappingType) -> Self {
762 match wrapping {
763 wit::WrappingType::NonNull => WrappingType::NonNull,
764 wit::WrappingType::List => WrappingType::List,
765 }
766 }
767}
768
769#[derive(Clone, Copy)]
773pub struct InputValueDefinition<'a> {
774 pub(crate) schema: &'a IndexedSchema,
775 pub(crate) definition: &'a wit::InputValueDefinition,
776}
777
778impl fmt::Debug for InputValueDefinition<'_> {
779 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
780 f.debug_struct("InputValueDefinition")
781 .field("id", &self.id())
782 .field("name", &self.name())
783 .field("type", &self.ty())
784 .field("directives", &self.directives().collect::<Vec<_>>())
785 .finish()
786 }
787}
788
789impl<'a> From<(&'a IndexedSchema, &'a wit::InputValueDefinition)> for InputValueDefinition<'a> {
790 fn from((schema, definition): (&'a IndexedSchema, &'a wit::InputValueDefinition)) -> Self {
791 Self { schema, definition }
792 }
793}
794
795impl<'a> InputValueDefinition<'a> {
796 pub fn id(&self) -> DefinitionId {
798 DefinitionId(self.definition.id)
799 }
800
801 pub fn name(&self) -> &'a str {
803 self.definition.name.as_str()
804 }
805
806 pub fn ty(&self) -> Type<'a> {
808 (self.schema, &self.definition.ty).into()
809 }
810
811 pub fn directives(&self) -> impl ExactSizeIterator<Item = Directive<'a>> + 'a {
813 self.definition.directives.iter().map(Into::into)
814 }
815}
816
817#[derive(Clone, Copy)]
819pub struct EnumValue<'a>(&'a wit::EnumValue);
820
821impl fmt::Debug for EnumValue<'_> {
822 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
823 f.debug_struct("EnumValue")
824 .field("name", &self.name())
825 .field("directives", &self.directives().collect::<Vec<_>>())
826 .finish()
827 }
828}
829
830impl<'a> From<&'a wit::EnumValue> for EnumValue<'a> {
831 fn from(enum_value: &'a wit::EnumValue) -> Self {
832 Self(enum_value)
833 }
834}
835
836impl<'a> EnumValue<'a> {
837 pub fn name(&self) -> &'a str {
839 self.0.name.as_str()
840 }
841
842 pub fn directives(&self) -> impl ExactSizeIterator<Item = Directive<'a>> + 'a {
844 self.0.directives.iter().map(Into::into)
845 }
846}
847
848#[derive(Clone, Copy)]
853pub struct Directive<'a>(pub(crate) DirectiveInner<'a>);
854
855#[derive(Clone, Copy)]
857pub(crate) enum DirectiveInner<'a> {
858 Wit(&'a wit::Directive),
859 NameAndArgs { name: &'a str, arguments: &'a [u8] },
860}
861
862impl fmt::Debug for Directive<'_> {
863 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
864 f.debug_struct("Directive")
865 .field("name", &self.name())
866 .field("arguments", &"<binary arguments>")
867 .finish()
868 }
869}
870
871impl<'a> From<&'a wit::Directive> for Directive<'a> {
872 fn from(directive: &'a wit::Directive) -> Self {
873 Self(DirectiveInner::Wit(directive))
874 }
875}
876
877impl<'a> Directive<'a> {
878 pub fn name(&self) -> &'a str {
880 match &self.0 {
881 DirectiveInner::Wit(directive) => directive.name.as_str(),
882 DirectiveInner::NameAndArgs { name, .. } => name,
883 }
884 }
885
886 pub fn arguments<T>(&self) -> Result<T, SdkError>
888 where
889 T: Deserialize<'a>,
890 {
891 cbor::from_slice::<T>(self.arguments_bytes()).map_err(Into::into)
892 }
893
894 #[inline]
896 pub fn arguments_seed<T>(&self, seed: T) -> Result<T::Value, SdkError>
897 where
898 T: serde::de::DeserializeSeed<'a>,
899 {
900 cbor::from_slice_with_seed(self.arguments_bytes(), seed).map_err(Into::into)
901 }
902
903 fn arguments_bytes(&self) -> &'a [u8] {
904 match &self.0 {
905 DirectiveInner::Wit(directive) => &directive.arguments,
906 DirectiveInner::NameAndArgs { arguments, .. } => arguments,
907 }
908 }
909}