use super::avatar_id_hasher::AvatarIdHasher;
use super::part_key_resolver;
use super::part_number_mapper;
pub const PART_ORDER: [&str; 6] = ["env", "head", "clo", "top", "eyes", "mouth"];
#[derive(Debug, Clone)]
pub struct AvatarSpec {
part_keys: Vec<(String, String)>,
}
impl AvatarSpec {
pub fn resolve(
input: &str,
hasher: &dyn AvatarIdHasher,
forced_part: Option<&str>,
forced_theme: Option<&str>,
) -> AvatarSpec {
let numbers = part_number_mapper::map(&hasher.hash12(input));
let mut keys: Vec<(String, String)> = numbers
.iter()
.map(|(part, nr)| (part.clone(), part_key_resolver::resolve(*nr)))
.collect();
if forced_part.is_some() || forced_theme.is_some() {
for (_, k) in keys.iter_mut() {
let part_v = forced_part.unwrap_or(&k[0..2]);
let theme = forced_theme.unwrap_or(&k[2..3]);
*k = format!("{}{}", part_v, theme);
}
}
AvatarSpec { part_keys: keys }
}
pub fn part_key_of(&self, part_name: &str) -> Option<&str> {
self.part_keys
.iter()
.find(|(p, _)| p == part_name)
.map(|(_, k)| k.as_str())
}
pub fn part_v_of(&self, part_name: &str) -> Option<&str> {
self.part_key_of(part_name).map(|k| &k[0..2])
}
pub fn theme_of(&self, part_name: &str) -> Option<&str> {
self.part_key_of(part_name).map(|k| &k[2..3])
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::core::avatar_id_hasher::Sha256AvatarIdHasher;
#[test]
fn resolve_auto_keys() {
let spec = AvatarSpec::resolve("Binx Bond", &Sha256AvatarIdHasher, None, None);
for part in PART_ORDER {
assert!(spec.part_key_of(part).is_some());
}
for part in PART_ORDER {
let k = spec.part_key_of(part).unwrap();
assert_eq!(k.len(), 3);
assert!(k.ends_with('A') || k.ends_with('B') || k.ends_with('C'));
}
}
#[test]
fn resolve_forced() {
let spec = AvatarSpec::resolve(
"Binx Bond",
&Sha256AvatarIdHasher,
Some("07"),
Some("B"),
);
for part in PART_ORDER {
assert_eq!(spec.part_key_of(part), Some("07B"));
}
}
#[test]
fn resolve_forced_part_only() {
let spec = AvatarSpec::resolve("Binx Bond", &Sha256AvatarIdHasher, Some("00"), None);
for part in PART_ORDER {
let k = spec.part_key_of(part).unwrap();
assert_eq!(&k[0..2], "00");
assert!(k.ends_with('A') || k.ends_with('B') || k.ends_with('C'));
}
}
}