extern crate serde;
extern crate serde_json;
use crate::annalisa::LoadableDevice as _;
use crate::samplic::LoadableDevice as _;
use crate::{
file_load_json, CalibrationDescription, DeviceDescription,
LoadPathPattern, LoadableDevice, Result, Sampling,
};
use indexmap::IndexSet;
use std::path::{Path, PathBuf};
#[derive(Debug)]
pub struct Device<P: AsRef<Path>> {
pub system_path: P,
pub config_path: P,
pub data_path: P,
pub product_id: String,
}
impl<P: AsRef<Path>> Device<P> {
pub fn samplic(&self) -> crate::samplic::filesystem::Device<P> {
crate::samplic::filesystem::Device::new(self)
}
pub fn ommui(&self) -> crate::ommui::filesystem::Device<P> {
crate::ommui::filesystem::Device::new(self)
}
pub fn annalisa(&self) -> crate::annalisa::filesystem::Device<P> {
crate::annalisa::filesystem::Device::new(self)
}
pub fn system_dir(&self) -> PathBuf {
self.system_path.as_ref().to_path_buf()
}
pub fn config_dir(&self) -> PathBuf {
self.config_path.as_ref().to_path_buf()
}
pub fn data_dir(&self) -> PathBuf {
self.data_path.as_ref().to_path_buf()
}
pub fn samplic_dir(&self) -> PathBuf {
self.system_dir().join("samplic")
}
pub fn description_dir(&self) -> PathBuf {
self.system_dir().join("description")
}
pub fn description_calibrations_dir(&self) -> PathBuf {
self.description_dir().join("calibration")
}
pub fn samplings_dir(&self) -> PathBuf {
self.description_dir().join("sampling")
}
pub fn sampling_dir(&self, sampling_id: &str) -> PathBuf {
self.samplings_dir().join(sampling_id)
}
pub fn description_calibration_dir(
&self,
calibration_id: &str,
) -> PathBuf {
self.description_calibrations_dir().join(calibration_id)
}
pub fn device_dir(&self) -> PathBuf {
self.description_dir().join("device")
}
}
impl<P: AsRef<Path>> LoadableDevice for Device<P> {
fn load_calibration_description_index(
&self,
) -> Result<IndexSet<String>> {
IndexSet::load_path_pattern_from_dir(
self.description_calibrations_dir(),
"*",
)
}
fn load_calibration_description(
&self,
calibration_id: &str,
) -> Result<CalibrationDescription> {
use crate::ommui::LoadableDevice;
Ok(CalibrationDescription {
ommui: self
.ommui()
.load_calibration_description(calibration_id)?,
})
}
fn load_sampling_index(&self) -> Result<IndexSet<String>> {
IndexSet::load_path_pattern_from_dir(self.samplings_dir(), "*")
}
fn load_sampling(&self, sampling_id: &str) -> Result<Sampling> {
Ok(Sampling {
samplic: self.samplic().load_sampling(sampling_id)?,
annalisa: self.annalisa().load_sampling(sampling_id)?,
})
}
fn load_device_description(&self) -> Result<DeviceDescription> {
Ok(DeviceDescription {
samplic: self.samplic().load_device_description()?,
})
}
fn load_device(&self) -> Result<crate::Device> {
Ok(crate::Device {
description: self.load_device_description()?,
calibrations: self.load_calibration_descriptions()?,
system_profiles: self.samplic().load_system_profiles()?,
user_profiles: self.samplic().load_user_profiles()?,
samplings: self.load_samplings()?,
icons: self.samplic().load_icons()?,
translations: self.samplic().load_translations()?,
})
}
}
pub struct DeviceBuilder {
system_path: PathBuf,
base_config_path: PathBuf,
base_data_path: PathBuf,
product_id: String,
}
const DEFAULT_COMPANY_ID: &str = "ommui";
fn default_system_path_for_company_id(company_id: &str) -> PathBuf {
Path::new("/").join("etc").join(company_id).join("device")
}
impl DeviceBuilder {
pub fn new(product_id: &str) -> Self {
let dirs =
directories::ProjectDirs::from(product_id, "OMMUI", "OMMUI")
.expect("Could not determine project directory");
DeviceBuilder {
system_path: default_system_path_for_company_id(
DEFAULT_COMPANY_ID,
),
base_config_path: dirs.config_dir().to_path_buf(),
base_data_path: dirs.data_dir().to_path_buf(),
product_id: product_id.to_string(),
}
}
pub fn system_path_for_company_id(mut self, company_id: &str) -> Self {
self.system_path = default_system_path_for_company_id(company_id);
self
}
pub fn base_config_path<P: AsRef<Path>>(mut self, p: P) -> Self {
self.base_config_path = p.as_ref().to_path_buf();
self
}
pub fn base_data_path<P: AsRef<Path>>(mut self, p: P) -> Self {
self.base_data_path = p.as_ref().to_path_buf();
self
}
pub fn build(self) -> Result<Device<PathBuf>> {
let description =
file_load_json::<crate::samplic::DeviceDescription, _>(
self.system_path
.join("description")
.join("device")
.join("samplic")
.join("device.json"),
)?;
let device_id = description.uuid.to_hyphenated().to_string();
let config_path = self.base_config_path.join(&device_id);
let data_path = self.base_data_path.join(&device_id);
Ok(Device {
system_path: self.system_path,
config_path,
data_path,
product_id: self.product_id,
})
}
}