use crate::request::context::RequestContext;
use std::collections::{HashMap, HashSet};
use std::fmt::Display;
use std::hash::Hash;
pub trait RelationshipTrait: Display {
fn get_object(&self) -> &'static str;
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub(crate) struct RelationshipKey {
object: &'static str,
lazy: bool,
}
#[derive(Default)]
pub struct RelationshipStorage {
storage: HashMap<RelationshipKey, HashSet<String>>,
}
impl RelationshipStorage {
pub fn add_relationship(&mut self, relationship: impl RelationshipTrait) {
self.storage
.entry(RelationshipKey {
object: relationship.get_object(),
lazy: false,
})
.or_default()
.insert(relationship.to_string());
}
pub fn add_relationship_lazy(&mut self, relationship: impl RelationshipTrait) {
self.storage
.entry(RelationshipKey {
object: relationship.get_object(),
lazy: true,
})
.or_default()
.insert(relationship.to_string());
}
pub fn build_query_drain(&mut self, request_context: &mut RequestContext) {
for (relationship, include) in self.storage.drain() {
let key = match relationship.lazy {
true => format!("relate[{}]", relationship.object),
false => format!("include[{}]", relationship.object),
};
let include = include.into_iter().collect::<Vec<_>>().join(",");
request_context.query.push((key, include));
}
}
}