use std::collections::HashMap;
use syn::Ident;
use crate::errors::GetSpan;
#[derive(thiserror::Error, Debug)]
#[error("A dbstruct can only have 254 fields")]
pub struct Error {
span: proc_macro2::Span,
}
impl GetSpan for Error {
fn span(&self) -> proc_macro2::Span {
self.span
}
}
type Prefix = u8;
#[derive(Debug)]
pub struct DbKey(HashMap<Ident, Prefix>);
impl DbKey {
#[cfg(test)]
pub(crate) fn mock() -> Self {
Self(
["test_a", "test_b", "test_c", "test_d"]
.into_iter()
.map(|id| Ident::new(id, proc_macro2::Span::call_site()))
.enumerate()
.map(|(a, b)| (b, a as u8))
.collect(),
)
}
pub(crate) fn new(fields: &syn::Fields) -> Result<Self, Error> {
let mut idents: Vec<_> = fields
.iter()
.map(|f| f.ident.clone())
.map(|i| i.expect("should already be verified this is a named struct"))
.collect();
idents.sort();
if let Some(ident) = idents.get(u8::MAX as usize) {
return Err(Error { span: ident.span() });
};
let map = idents
.into_iter()
.enumerate()
.map(|(id, ident)| (ident, id as Prefix))
.collect();
Ok(Self(map))
}
pub fn prefix(&self, ident: &Ident) -> Prefix {
*self
.0
.get(ident)
.expect("every field's ident should be in the DbKey map")
}
}