am_api/request/
relationship.rs

1//! Request builder that supports relations
2
3use crate::request::context::RequestContext;
4use std::collections::{HashMap, HashSet};
5use std::fmt::Display;
6use std::hash::Hash;
7
8/// A trait for getting information about a relationship type
9pub trait RelationshipTrait: Display {
10    /// Get relation object name
11    fn get_object(&self) -> &'static str;
12}
13
14/// Relationship key
15#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
16pub(crate) struct RelationshipKey {
17    object: &'static str,
18    lazy: bool,
19}
20
21/// Relationship storage type
22#[derive(Default)]
23pub struct RelationshipStorage {
24    storage: HashMap<RelationshipKey, HashSet<String>>,
25}
26
27impl RelationshipStorage {
28    /// Add a relationship to this storage
29    pub fn add_relationship(&mut self, relationship: impl RelationshipTrait) {
30        self.storage
31            .entry(RelationshipKey {
32                object: relationship.get_object(),
33                lazy: false,
34            })
35            .or_default()
36            .insert(relationship.to_string());
37    }
38
39    /// Add a lazy relationship to this storage
40    pub fn add_relationship_lazy(&mut self, relationship: impl RelationshipTrait) {
41        self.storage
42            .entry(RelationshipKey {
43                object: relationship.get_object(),
44                lazy: true,
45            })
46            .or_default()
47            .insert(relationship.to_string());
48    }
49
50    /// Build relationship query parameters draining this storage
51    pub fn build_query_drain(&mut self, request_context: &mut RequestContext) {
52        for (relationship, include) in self.storage.drain() {
53            let key = match relationship.lazy {
54                true => format!("relate[{}]", relationship.object),
55                false => format!("include[{}]", relationship.object),
56            };
57
58            let include = include.into_iter().collect::<Vec<_>>().join(",");
59
60            request_context.query.push((key, include));
61        }
62    }
63}