graphql_federated_graph/federated_graph/
view.rs

1//! Convenient methods and helper types to navigate a [FederatedGraph].
2
3use std::ops::{Deref, Index};
4
5use super::{FederatedGraph, StringId};
6
7pub struct View<Id, Record> {
8    pub(super) id: Id,
9    pub(super) record: Record,
10}
11
12impl<Id, Record> View<Id, Record>
13where
14    Id: Copy,
15{
16    pub fn id(&self) -> Id {
17        self.id
18    }
19}
20
21impl<Id, Record> AsRef<Record> for View<Id, Record> {
22    fn as_ref(&self) -> &Record {
23        &self.record
24    }
25}
26
27impl<Id, Record> std::ops::Deref for View<Id, Record> {
28    type Target = Record;
29
30    fn deref(&self) -> &Self::Target {
31        &self.record
32    }
33}
34
35pub struct ViewNested<'a, Id, Record> {
36    pub(super) graph: &'a FederatedGraph,
37    pub(super) view: View<Id, &'a Record>,
38}
39
40impl<'a, Id, Record> Deref for ViewNested<'a, Id, Record> {
41    type Target = View<Id, &'a Record>;
42
43    fn deref(&self) -> &Self::Target {
44        &self.view
45    }
46}
47
48impl<'a, Id, Record> AsRef<View<Id, &'a Record>> for ViewNested<'a, Id, Record> {
49    fn as_ref(&self) -> &View<Id, &'a Record> {
50        &self.view
51    }
52}
53
54impl<Id, Record> AsRef<Record> for ViewNested<'_, Id, Record> {
55    fn as_ref(&self) -> &Record {
56        self.view.as_ref()
57    }
58}
59
60impl<'a, Id, Record> ViewNested<'a, Id, Record> {
61    /// Continue navigating with the next ID.
62    pub fn then<NextId, NextRecord>(&self, next: impl FnOnce(&Record) -> NextId) -> ViewNested<'a, NextId, NextRecord>
63    where
64        NextId: Copy,
65        FederatedGraph: Index<NextId, Output = NextRecord>,
66    {
67        self.graph.at(next(self.view.record))
68    }
69}
70
71impl FederatedGraph {
72    /// Start navigating the graph from the given ID. Returns a [ViewNested] that exposes further steps.
73    pub fn at<Id, Record>(&self, id: Id) -> ViewNested<'_, Id, Record>
74    where
75        Id: Copy,
76        FederatedGraph: Index<Id, Output = Record>,
77    {
78        ViewNested {
79            graph: self,
80            view: self.view(id),
81        }
82    }
83
84    /// Resolve a [StringId].
85    pub fn str(&self, id: StringId) -> &str {
86        self[id].as_str()
87    }
88
89    /// View the record with the given ID.
90    pub fn view<Id, Record>(&self, id: Id) -> View<Id, &Record>
91    where
92        Id: Copy,
93        FederatedGraph: Index<Id, Output = Record>,
94    {
95        View { id, record: &self[id] }
96    }
97}