Struct async_graphql::context::Data

source ·
pub struct Data(_);
Expand description

Schema/Context data.

This is a type map, allowing you to store anything inside it.

Implementations§

Insert data.

Examples found in repository?
src/dynamic/schema.rs (line 50)
49
50
51
52
    pub fn data<D: Any + Send + Sync>(mut self, data: D) -> Self {
        self.data.insert(data);
        self
    }
More examples
Hide additional examples
src/request.rs (line 92)
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
    pub fn data<D: Any + Send + Sync>(mut self, data: D) -> Self {
        self.data.insert(data);
        self
    }

    /// Disable introspection queries for this request.
    #[must_use]
    pub fn disable_introspection(mut self) -> Self {
        self.introspection_mode = IntrospectionMode::Disabled;
        self
    }

    /// Only allow introspection queries for this request.
    #[must_use]
    pub fn only_introspection(mut self) -> Self {
        self.introspection_mode = IntrospectionMode::IntrospectionOnly;
        self
    }

    #[inline]
    /// Performs parsing of query ahead of execution.
    ///
    /// This effectively allows to inspect query information, before passing
    /// request to schema for execution as long as query is valid.
    pub fn parsed_query(&mut self) -> Result<&ExecutableDocument, ServerError> {
        if self.parsed_query.is_none() {
            match parse_query(&self.query) {
                Ok(parsed) => self.parsed_query = Some(parsed),
                Err(error) => return Err(error.into()),
            }
        }

        // forbid_unsafe effectively bans optimize away else branch here so use unwrap
        // but this unwrap never panics
        Ok(self.parsed_query.as_ref().unwrap())
    }

    /// Set a variable to an upload value.
    ///
    /// `var_path` is a dot-separated path to the item that begins with
    /// `variables`, for example `variables.files.2.content` is equivalent
    /// to the Rust code `request.variables["files"][2]["content"]`. If no
    /// variable exists at the path this function won't do anything.
    pub fn set_upload(&mut self, var_path: &str, upload: UploadValue) {
        fn variable_path<'a>(variables: &'a mut Variables, path: &str) -> Option<&'a mut Value> {
            let mut parts = path.strip_prefix("variables.")?.split('.');

            let initial = variables.get_mut(parts.next().unwrap())?;

            parts.try_fold(initial, |current, part| match current {
                Value::List(list) => part
                    .parse::<u32>()
                    .ok()
                    .and_then(|idx| usize::try_from(idx).ok())
                    .and_then(move |idx| list.get_mut(idx)),
                Value::Object(obj) => obj.get_mut(part),
                _ => None,
            })
        }

        let variable = match variable_path(&mut self.variables, var_path) {
            Some(variable) => variable,
            None => return,
        };
        self.uploads.push(upload);
        *variable = Value::String(format!("#__graphql_file__:{}", self.uploads.len() - 1));
    }
}

impl<T: Into<String>> From<T> for Request {
    fn from(query: T) -> Self {
        Self::new(query)
    }
}

impl Debug for Request {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        f.debug_struct("Request")
            .field("query", &self.query)
            .field("operation_name", &self.operation_name)
            .field("variables", &self.variables)
            .field("extensions", &self.extensions)
            .finish()
    }
}

/// Batch support for GraphQL requests, which is either a single query, or an
/// array of queries
///
/// **Reference:** <https://www.apollographql.com/blog/batching-client-graphql-queries-a685f5bcd41b/>
#[derive(Debug, Deserialize)]
#[serde(untagged)]
#[allow(clippy::large_enum_variant)] // Request is at fault
pub enum BatchRequest {
    /// Single query
    Single(Request),

    /// Non-empty array of queries
    #[serde(deserialize_with = "deserialize_non_empty_vec")]
    Batch(Vec<Request>),
}

impl BatchRequest {
    /// Attempt to convert the batch request into a single request.
    ///
    /// # Errors
    ///
    /// Fails if the batch request is a list of requests with a message saying
    /// that batch requests aren't supported.
    pub fn into_single(self) -> Result<Request, ParseRequestError> {
        match self {
            Self::Single(req) => Ok(req),
            Self::Batch(_) => Err(ParseRequestError::UnsupportedBatch),
        }
    }

    /// Returns an iterator over the requests.
    pub fn iter(&self) -> impl Iterator<Item = &Request> {
        match self {
            BatchRequest::Single(request) => {
                Box::new(std::iter::once(request)) as Box<dyn Iterator<Item = &Request>>
            }
            BatchRequest::Batch(requests) => Box::new(requests.iter()),
        }
    }

    /// Returns an iterator that allows modifying each request.
    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut Request> {
        match self {
            BatchRequest::Single(request) => {
                Box::new(std::iter::once(request)) as Box<dyn Iterator<Item = &mut Request>>
            }
            BatchRequest::Batch(requests) => Box::new(requests.iter_mut()),
        }
    }

    /// Specify the variables for each requests.
    #[must_use]
    pub fn variables(mut self, variables: Variables) -> Self {
        for request in self.iter_mut() {
            request.variables = variables.clone();
        }
        self
    }

    /// Insert some data for  for each requests.
    #[must_use]
    pub fn data<D: Any + Clone + Send + Sync>(mut self, data: D) -> Self {
        for request in self.iter_mut() {
            request.data.insert(data.clone());
        }
        self
    }
src/schema.rs (line 153)
152
153
154
155
    pub fn data<D: Any + Send + Sync>(mut self, data: D) -> Self {
        self.data.insert(data);
        self
    }

Methods from Deref<Target = FnvHashMap<TypeId, Box<dyn Any + Sync + Send>>>§

Returns the number of elements the map can hold without reallocating.

This number is a lower bound; the HashMap<K, V> might be able to hold more, but is guaranteed to be able to hold at least this many.

Examples
use std::collections::HashMap;
let map: HashMap<i32, i32> = HashMap::with_capacity(100);
assert!(map.capacity() >= 100);

An iterator visiting all keys in arbitrary order. The iterator element type is &'a K.

Examples
use std::collections::HashMap;

let map = HashMap::from([
    ("a", 1),
    ("b", 2),
    ("c", 3),
]);

for key in map.keys() {
    println!("{key}");
}
Performance

In the current implementation, iterating over keys takes O(capacity) time instead of O(len) because it internally visits empty buckets too.

An iterator visiting all values in arbitrary order. The iterator element type is &'a V.

Examples
use std::collections::HashMap;

let map = HashMap::from([
    ("a", 1),
    ("b", 2),
    ("c", 3),
]);

for val in map.values() {
    println!("{val}");
}
Performance

In the current implementation, iterating over values takes O(capacity) time instead of O(len) because it internally visits empty buckets too.

An iterator visiting all key-value pairs in arbitrary order. The iterator element type is (&'a K, &'a V).

Examples
use std::collections::HashMap;

let map = HashMap::from([
    ("a", 1),
    ("b", 2),
    ("c", 3),
]);

for (key, val) in map.iter() {
    println!("key: {key} val: {val}");
}
Performance

In the current implementation, iterating over map takes O(capacity) time instead of O(len) because it internally visits empty buckets too.

Returns the number of elements in the map.

Examples
use std::collections::HashMap;

let mut a = HashMap::new();
assert_eq!(a.len(), 0);
a.insert(1, "a");
assert_eq!(a.len(), 1);

Returns true if the map contains no elements.

Examples
use std::collections::HashMap;

let mut a = HashMap::new();
assert!(a.is_empty());
a.insert(1, "a");
assert!(!a.is_empty());

Returns a reference to the map’s BuildHasher.

Examples
use std::collections::HashMap;
use std::collections::hash_map::RandomState;

let hasher = RandomState::new();
let map: HashMap<i32, i32> = HashMap::with_hasher(hasher);
let hasher: &RandomState = map.hasher();

Returns a reference to the value corresponding to the key.

The key may be any borrowed form of the map’s key type, but Hash and Eq on the borrowed form must match those for the key type.

Examples
use std::collections::HashMap;

let mut map = HashMap::new();
map.insert(1, "a");
assert_eq!(map.get(&1), Some(&"a"));
assert_eq!(map.get(&2), None);

Returns the key-value pair corresponding to the supplied key.

The supplied key may be any borrowed form of the map’s key type, but Hash and Eq on the borrowed form must match those for the key type.

Examples
use std::collections::HashMap;

let mut map = HashMap::new();
map.insert(1, "a");
assert_eq!(map.get_key_value(&1), Some((&1, &"a")));
assert_eq!(map.get_key_value(&2), None);

Returns true if the map contains a value for the specified key.

The key may be any borrowed form of the map’s key type, but Hash and Eq on the borrowed form must match those for the key type.

Examples
use std::collections::HashMap;

let mut map = HashMap::new();
map.insert(1, "a");
assert_eq!(map.contains_key(&1), true);
assert_eq!(map.contains_key(&2), false);
source

pub fn raw_entry(&self) -> RawEntryBuilder<'_, K, V, S>

🔬This is a nightly-only experimental API. (hash_raw_entry)

Creates a raw immutable entry builder for the HashMap.

Raw entries provide the lowest level of control for searching and manipulating a map. They must be manually initialized with a hash and then manually searched.

This is useful for

  • Hash memoization
  • Using a search key that doesn’t work with the Borrow trait
  • Using custom comparison logic without newtype wrappers

Unless you are in such a situation, higher-level and more foolproof APIs like get should be preferred.

Immutable raw entries have very limited use; you might instead want raw_entry_mut.

Trait Implementations§

Formats the value using the given formatter. Read more
Returns the “default value” for a type. Read more
The resulting type after dereferencing.
Dereferences the value.

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
Attaches the current Context to this type, returning a WithContext wrapper. Read more
Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Instruments this type with the current Span, returning an Instrumented wrapper. Read more

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Should always be Self
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more