use serde::{Deserialize, Serialize};
use uuid::Uuid;
use crate::{ProfileData, ProfileError, ProfileStore};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DeviceIdentity {
pub device_instance_id: Uuid,
pub device_name: String,
}
impl ProfileData for DeviceIdentity {
const FILENAME: &'static str = "device.json";
const MODE: Option<u32> = Some(0o600);
}
impl DeviceIdentity {
pub fn load_or_create(store: &ProfileStore) -> Result<Self, ProfileError> {
match store.load_profile::<Self>() {
Ok(identity) => Ok(identity),
Err(ProfileError::NotFound { .. }) => {
let identity = Self {
device_instance_id: Uuid::new_v4(),
device_name: gethostname::gethostname().to_string_lossy().into_owned(),
};
store.save_profile(&identity)?;
Ok(identity)
}
Err(e) => Err(e),
}
}
pub fn load(store: &ProfileStore) -> Result<Self, ProfileError> {
store.load_profile()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn load_or_create_generates_new_identity() {
let dir = tempfile::tempdir().unwrap();
let store = ProfileStore::new(dir.path());
let identity = DeviceIdentity::load_or_create(&store).unwrap();
assert!(!identity.device_instance_id.is_nil());
assert!(!identity.device_name.is_empty());
}
#[test]
fn load_or_create_reuses_existing() {
let dir = tempfile::tempdir().unwrap();
let store = ProfileStore::new(dir.path());
let first = DeviceIdentity::load_or_create(&store).unwrap();
let second = DeviceIdentity::load_or_create(&store).unwrap();
assert_eq!(first.device_instance_id, second.device_instance_id);
assert_eq!(first.device_name, second.device_name);
}
#[test]
fn load_returns_not_found_for_missing_file() {
let dir = tempfile::tempdir().unwrap();
let store = ProfileStore::new(dir.path());
let err = DeviceIdentity::load(&store).unwrap_err();
assert!(matches!(err, ProfileError::NotFound { .. }));
}
#[test]
fn round_trip_serialization() {
let dir = tempfile::tempdir().unwrap();
let store = ProfileStore::new(dir.path());
let original = DeviceIdentity {
device_instance_id: Uuid::new_v4(),
device_name: "test-host".to_string(),
};
store.save("device.json", &original).unwrap();
let loaded = DeviceIdentity::load(&store).unwrap();
assert_eq!(original.device_instance_id, loaded.device_instance_id);
assert_eq!(original.device_name, loaded.device_name);
}
}