grafbase_sdk/
types.rs

1//! Type definitions of the input and output data structures of the SDK.
2
3mod authorization;
4mod directive;
5mod directive_site;
6mod elements;
7mod error;
8mod error_response;
9
10pub use authorization::*;
11pub use directive::*;
12pub use directive_site::*;
13pub use elements::*;
14pub use error::*;
15pub use error_response::*;
16
17pub use http::StatusCode;
18pub use serde::Deserialize;
19use serde::Serialize;
20
21use crate::{cbor, wit};
22
23/// Output responses from the field resolver.
24pub struct FieldOutput(wit::FieldOutput);
25
26impl Default for FieldOutput {
27    fn default() -> Self {
28        Self::new()
29    }
30}
31
32impl FieldOutput {
33    /// Construct a new output response.
34    pub fn new() -> Self {
35        Self(wit::FieldOutput { outputs: Vec::new() })
36    }
37
38    /// Constructs a new, empty output with at least the specified capacity.
39    ///
40    /// The output will be able to hold at least `capacity` elements without
41    /// reallocating.
42    pub fn with_capacity(capacity: usize) -> Self {
43        Self(wit::FieldOutput {
44            outputs: Vec::with_capacity(capacity),
45        })
46    }
47
48    /// Push a new output data to the response.
49    pub fn push_value<T>(&mut self, output: T)
50    where
51        T: Serialize,
52    {
53        let output = crate::cbor::to_vec(output).expect("serialization error is Infallible, so it should never happen");
54
55        self.0.outputs.push(Ok(output));
56    }
57
58    /// Push a new error to the response.
59    pub fn push_error(&mut self, error: impl Into<Error>) {
60        self.0.outputs.push(Err(Into::<Error>::into(error).into()));
61    }
62}
63
64impl From<FieldOutput> for wit::FieldOutput {
65    fn from(value: FieldOutput) -> Self {
66        value.0
67    }
68}
69
70/// A container for field inputs.
71#[derive(Debug)]
72pub struct FieldInputs(Vec<Vec<u8>>);
73
74impl FieldInputs {
75    pub(crate) fn new(inputs: Vec<Vec<u8>>) -> Self {
76        Self(inputs)
77    }
78
79    /// Deserializes each byte slice in the `FieldInputs` to a collection of items.
80    pub fn deserialize<'de, T>(&'de self) -> Result<Vec<T>, Box<dyn std::error::Error>>
81    where
82        T: Deserialize<'de>,
83    {
84        self.0
85            .iter()
86            .map(|input| cbor::from_slice(input).map_err(|e| Box::new(e) as Box<dyn std::error::Error>))
87            .collect()
88    }
89}
90
91/// Configuration data for the extension, from the gateway toml config.
92pub struct Configuration(Vec<u8>);
93
94impl Configuration {
95    /// Creates a new `Configuration` from a CBOR byte vector.
96    pub(crate) fn new(config: Vec<u8>) -> Self {
97        Self(config)
98    }
99
100    /// Deserializes the configuration bytes into the requested type.
101    ///
102    /// # Errors
103    ///
104    /// Returns an error if deserialization fails.
105    pub fn deserialize<'de, T>(&'de self) -> Result<T, Box<dyn std::error::Error>>
106    where
107        T: Deserialize<'de>,
108    {
109        cbor::from_slice(&self.0).map_err(|e| Box::new(e) as Box<dyn std::error::Error>)
110    }
111}
112
113/// A cache implementation for storing data between requests.
114pub struct Cache;
115
116/// A structure representing an authentication token claims.
117pub struct Token {
118    claims: Vec<u8>,
119}
120
121impl From<Token> for wit::Token {
122    fn from(token: Token) -> wit::Token {
123        wit::Token { raw: token.claims }
124    }
125}
126
127impl Token {
128    /// Creates a new `Token` with the given claims. The claims can be defined by the extension,
129    /// but to use the [`@requiredScopes`](https://grafbase.com/docs/reference/graphql-directives#requiresscopes)
130    /// directive, the claims must contain a `scopes` field with an array of strings.
131    pub fn new<T>(claims: T) -> Self
132    where
133        T: serde::Serialize,
134    {
135        Self {
136            claims: cbor::to_vec(&claims).expect("serialization error is Infallible, so it should never happen"),
137        }
138    }
139}