extern crate serde;
extern crate serde_json;
use crate::arnalisa::LoadableDevice as _;
use crate::arnalisamplic::LoadableDevice as _;
use crate::ommui::LoadableDevice as _;
use crate::samplic::LoadableDevice as _;
use crate::xio::LoadableDevice as _;
use crate::xiolisa::LoadableDevice as _;
use crate::{
file_load_json, CalibrationDescription, DeviceDescription,
LoadPathPattern, LoadableDevice, Result, Sampling, StorableDevice,
};
use indexmap::IndexSet;
use std::path::{Path, PathBuf};
#[derive(Clone, Debug)]
pub struct Device {
pub system_path: PathBuf,
pub config_path: PathBuf,
pub data_path: PathBuf,
pub cache_path: PathBuf,
pub product_id: String,
}
impl Device {
pub fn system_dir(&self) -> PathBuf {
self.system_path.clone()
}
pub fn config_dir(&self) -> PathBuf {
self.config_path.clone()
}
pub fn data_dir(&self) -> PathBuf {
self.data_path.clone()
}
pub fn cache_dir(&self) -> PathBuf {
self.cache_path.clone()
}
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 LoadableDevice for Device {
type ArnalisaLoadableDevice = crate::arnalisa::filesystem::Device;
type ArnalisamplicLoadableDevice =
crate::arnalisamplic::filesystem::Device;
type OmmuiLoadableDevice = crate::ommui::filesystem::Device;
type SamplicLoadableDevice = crate::samplic::filesystem::Device;
type XioLoadableDevice = crate::xio::filesystem::Device;
type XiolisaLoadableDevice = crate::xiolisa::filesystem::Device;
fn arnalisa(&self) -> Self::ArnalisaLoadableDevice {
crate::arnalisa::filesystem::Device::new(self.clone())
}
fn arnalisamplic(&self) -> Self::ArnalisamplicLoadableDevice {
crate::arnalisamplic::filesystem::Device::new(self.clone())
}
fn ommui(&self) -> Self::OmmuiLoadableDevice {
crate::ommui::filesystem::Device::new(self.clone())
}
fn samplic(&self) -> Self::SamplicLoadableDevice {
crate::samplic::filesystem::Device::new(self.clone())
}
fn xio(&self) -> Self::XioLoadableDevice {
crate::xio::filesystem::Device::new(self.clone())
}
fn xiolisa(&self) -> Self::XiolisaLoadableDevice {
crate::xiolisa::filesystem::Device::new(self.clone())
}
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> {
Ok(CalibrationDescription {
arnalisa: self.arnalisa().load_calibration(calibration_id)?,
ommui: self
.ommui()
.load_calibration_description(calibration_id)?,
xiolisa: self.xiolisa().load_calibration(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 {
arnalisa: self.arnalisa().load_sampling(sampling_id)?,
arnalisamplic: self
.arnalisamplic()
.load_sampling(sampling_id)?,
ommui: self.ommui().load_sampling(sampling_id)?,
samplic: self.samplic().load_sampling(sampling_id)?,
xio: self.xio().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()?,
settings: {
if self.ommui().device_settings_file().exists() {
Some(self.ommui().load_device_settings()?)
} else {
None
}
},
samplings: self.load_samplings()?,
icons: self.samplic().load_icons()?,
units: self.samplic().load_units()?,
translations: self.samplic().load_translations()?,
})
}
}
impl StorableDevice for Device {
type OmmuiStorableDevice = crate::ommui::filesystem::Device;
type SamplicStorableDevice = crate::samplic::filesystem::Device;
fn ommui_storable(&self) -> Self::OmmuiStorableDevice {
crate::ommui::filesystem::Device::new(self.clone())
}
fn samplic_storable(&self) -> Self::SamplicStorableDevice {
crate::samplic::filesystem::Device::new(self.clone())
}
}
pub struct DeviceBuilder {
override_system_path: Option<PathBuf>,
override_base_config_path: Option<PathBuf>,
override_base_data_path: Option<PathBuf>,
override_base_cache_path: Option<PathBuf>,
product_id: String,
company_id: String,
}
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, company_id: &str) -> Self {
DeviceBuilder {
override_system_path: None,
override_base_config_path: None,
override_base_data_path: None,
override_base_cache_path: None,
product_id: product_id.to_string(),
company_id: company_id.to_string(),
}
}
pub fn base_system_path<P: AsRef<Path>>(mut self, p: P) -> Self {
self.override_system_path = Some(p.as_ref().to_path_buf());
self
}
pub fn base_config_path<P: AsRef<Path>>(mut self, p: P) -> Self {
self.override_base_config_path = Some(p.as_ref().to_path_buf());
self
}
pub fn base_data_path<P: AsRef<Path>>(mut self, p: P) -> Self {
self.override_base_data_path = Some(p.as_ref().to_path_buf());
self
}
pub fn build(self) -> Result<Device> {
let DeviceBuilder {
override_system_path,
override_base_config_path,
override_base_data_path,
override_base_cache_path,
product_id,
company_id,
} = self;
let dirs =
directories::ProjectDirs::from("at", &company_id, &product_id)
.expect("Could not determine project directory");
let system_path = override_system_path.unwrap_or_else(|| {
default_system_path_for_company_id(&company_id)
});
let description =
file_load_json::<crate::samplic::DeviceDescription, _>(
system_path
.join("description")
.join("device")
.join("samplic")
.join("device.json"),
)?;
let device_id = description.uuid.to_hyphenated().to_string();
let base_config_path = override_base_config_path
.unwrap_or_else(|| dirs.config_dir().to_path_buf());
let config_path = base_config_path.join(&device_id);
let base_data_path = override_base_data_path
.unwrap_or_else(|| dirs.data_dir().to_path_buf());
let data_path = base_data_path.join(&device_id);
let base_cache_path = override_base_cache_path
.unwrap_or_else(|| dirs.cache_dir().to_path_buf());
let cache_path = base_cache_path.join(&device_id);
Ok(Device {
system_path,
config_path,
data_path,
cache_path,
product_id,
})
}
}