use std::collections::HashMap;
use super::{AttributeDefinition, HasAttribute, HasTableKeyAttributes, TableDefinition};
use crate::{AttributeValue, IntoAttributeValue};
mod sealed_traits {
use super::*;
pub trait AttributeListSeal<TD: TableDefinition, T: HasTableKeyAttributes<TD>> {
const ATTRIBUTE_LIST_LEN: usize;
fn enrich(source: &T, item: &mut HashMap<String, AttributeValue>);
}
}
pub trait AttributeList<TD: TableDefinition, T: HasTableKeyAttributes<TD>>:
sealed_traits::AttributeListSeal<TD, T>
{
fn get_attributes(source: &T) -> HashMap<String, AttributeValue>;
}
impl<TD: TableDefinition, T: HasTableKeyAttributes<TD>> sealed_traits::AttributeListSeal<TD, T>
for ()
{
const ATTRIBUTE_LIST_LEN: usize = 0;
fn enrich(_source: &T, _item: &mut HashMap<String, AttributeValue>) {}
}
impl<TD, A, Rest, T> sealed_traits::AttributeListSeal<TD, T> for (A, Rest)
where
TD: TableDefinition,
A: AttributeDefinition,
T: HasTableKeyAttributes<TD> + HasAttribute<A>,
Rest: sealed_traits::AttributeListSeal<TD, T>,
{
const ATTRIBUTE_LIST_LEN: usize = Rest::ATTRIBUTE_LIST_LEN + 1;
fn enrich(source: &T, item: &mut HashMap<String, AttributeValue>) {
item.insert(
A::NAME.to_owned(),
<T as HasAttribute<A>>::attribute(source).into_attribute_value(),
);
Rest::enrich(source, item);
}
}
impl<TD, T, AL> AttributeList<TD, T> for AL
where
TD: TableDefinition,
T: HasTableKeyAttributes<TD>,
AL: sealed_traits::AttributeListSeal<TD, T>,
{
fn get_attributes(source: &T) -> HashMap<String, AttributeValue> {
let mut attributes = HashMap::with_capacity(AL::ATTRIBUTE_LIST_LEN);
Self::enrich(source, &mut attributes);
attributes
}
}