grafbase_sdk/types/
elements.rs

1use crate::{types::DirectiveSite, wit};
2
3/// A list of elements present in the query on which one of the extension's directive was applied on their definition.
4#[derive(Clone, Copy)]
5pub struct QueryElements<'a>(&'a wit::QueryElements);
6
7impl<'a> From<&'a wit::QueryElements> for QueryElements<'a> {
8    fn from(value: &'a wit::QueryElements) -> Self {
9        Self(value)
10    }
11}
12
13// is never empty, otherwise we wouldn't call the extension at all
14#[allow(clippy::len_without_is_empty)]
15impl<'a> QueryElements<'a> {
16    /// Number of elements within the query
17    pub fn len(&self) -> usize {
18        self.0.elements.len()
19    }
20
21    /// Iterate over all elements, regardless of the directive they're associated with. Useful if
22    /// expect only one directive to be used.
23    pub fn iter(&self) -> impl ExactSizeIterator<Item = QueryElement<'a>> + 'a {
24        self.0
25            .elements
26            .iter()
27            .enumerate()
28            .map(move |(ix, site)| QueryElement { site, ix: ix as u32 })
29    }
30
31    /// Iterate over all elements grouped by the directive name.
32    pub fn iter_grouped_by_directive_name(
33        &self,
34    ) -> impl ExactSizeIterator<Item = (&'a str, impl ExactSizeIterator<Item = QueryElement<'a>> + 'a)> + 'a {
35        let query = self.0;
36        self.0.directive_names.iter().map(|(name, start, end)| {
37            let start = *start;
38            (
39                name.as_str(),
40                query.elements[start as usize..*end as usize]
41                    .iter()
42                    .enumerate()
43                    .map(move |(i, site)| QueryElement {
44                        site,
45                        ix: start + i as u32,
46                    }),
47            )
48        })
49    }
50}
51
52/// An element of the query on which a directive was applied.
53#[derive(Clone, Copy)]
54pub struct QueryElement<'a> {
55    site: &'a wit::DirectiveSite,
56    pub(super) ix: u32,
57}
58
59impl<'a> QueryElement<'a> {
60    /// Site, where and with which arguments, of the directive associated with this element.
61    /// The provided arguments will exclude anything that depend on response data such as
62    /// `FieldSet`.
63    pub fn site(&self) -> DirectiveSite<'a> {
64        self.site.into()
65    }
66}