use std::collections::HashMap;
use std::fs;
use std::path::Path;
use crate::error::DecodeError;
use crate::profile::Profile;
use crate::profile_parser::parse_profiles_json;
#[derive(Debug, Clone)]
pub struct ProfileDb {
profiles: HashMap<i32, Profile>,
}
impl ProfileDb {
pub fn load_builtin() -> Result<Self, DecodeError> {
let json = include_str!("../data/profiles.json");
let profiles = parse_profiles_json(json)?;
let map: HashMap<i32, Profile> = profiles.into_iter().map(|p| (p.prefix, p)).collect();
Ok(Self { profiles: map })
}
pub fn load_external<P: AsRef<Path>>(&mut self, path: P) -> Result<(), DecodeError> {
let data = fs::read_to_string(path.as_ref())
.map_err(|e| DecodeError::Profile(format!("failed to read '{}': {e}", path.as_ref().display())))?;
let profiles = parse_profiles_json(&data)?;
for p in profiles {
self.profiles.insert(p.prefix, p);
}
Ok(())
}
#[must_use]
pub fn get(&self, prefix: i32) -> Option<&Profile> {
self.profiles.get(&prefix)
}
#[must_use]
pub fn all(&self) -> &HashMap<i32, Profile> {
&self.profiles
}
#[must_use]
pub fn len(&self) -> usize {
self.profiles.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.profiles.is_empty()
}
}
#[cfg(test)]
#[allow(clippy::unwrap_used)]
mod tests {
use super::*;
#[test]
fn load_builtin_has_54_profiles() {
let db = ProfileDb::load_builtin().unwrap();
assert_eq!(db.len(), 54);
}
#[test]
fn get_1007_returns_correct_profile() {
let db = ProfileDb::load_builtin().unwrap();
let p = db.get(1007).expect("profile 1007 should exist");
assert_eq!(p.prefix, 1007);
assert_eq!(p.width, 480);
assert_eq!(p.height, 864);
assert_eq!(p.encoding, crate::profile::Encoding::Rgb565);
assert_eq!(p.frame_byte_length, 829_440);
assert!(!p.is_padded);
assert!(p.little_endian); }
#[test]
fn get_9999_returns_none() {
let db = ProfileDb::load_builtin().unwrap();
assert!(db.get(9999).is_none());
}
#[test]
fn get_1061_has_use_mhni_dimensions() {
let db = ProfileDb::load_builtin().unwrap();
let p = db.get(1061).expect("profile 1061 should exist");
assert!(p.use_mhni_dimensions);
}
#[test]
fn get_3004_has_padded_slot() {
let db = ProfileDb::load_builtin().unwrap();
let p = db.get(3004).expect("profile 3004 should exist");
assert!(p.is_padded);
assert_eq!(p.slot_size, 8192);
assert_eq!(p.encoding, crate::profile::Encoding::Rgb555);
}
#[test]
fn all_returns_full_map() {
let db = ProfileDb::load_builtin().unwrap();
let all = db.all();
assert!(all.contains_key(&1007));
assert!(all.contains_key(&3011));
assert_eq!(all.len(), 54);
}
}