use crate::EntityId;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct Property {
pub name: String,
pub value: String,
pub unit: Option<String>,
}
impl Property {
pub fn new(name: impl Into<String>, value: impl Into<String>) -> Self {
Self {
name: name.into(),
value: value.into(),
unit: None,
}
}
pub fn with_unit(
name: impl Into<String>,
value: impl Into<String>,
unit: impl Into<String>,
) -> Self {
Self {
name: name.into(),
value: value.into(),
unit: Some(unit.into()),
}
}
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct PropertySet {
pub name: String,
pub properties: Vec<Property>,
}
impl PropertySet {
pub fn new(name: impl Into<String>) -> Self {
Self {
name: name.into(),
properties: Vec::new(),
}
}
pub fn add(&mut self, property: Property) {
self.properties.push(property);
}
pub fn get(&self, name: &str) -> Option<&Property> {
self.properties.iter().find(|p| p.name == name)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum QuantityType {
Length,
Area,
Volume,
Count,
Weight,
Time,
}
impl QuantityType {
pub fn default_unit(&self) -> &'static str {
match self {
QuantityType::Length => "m",
QuantityType::Area => "m²",
QuantityType::Volume => "m³",
QuantityType::Count => "",
QuantityType::Weight => "kg",
QuantityType::Time => "s",
}
}
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct Quantity {
pub name: String,
pub value: f64,
pub unit: String,
pub quantity_type: QuantityType,
}
impl Quantity {
pub fn new(name: impl Into<String>, value: f64, quantity_type: QuantityType) -> Self {
Self {
name: name.into(),
value,
unit: quantity_type.default_unit().to_string(),
quantity_type,
}
}
pub fn with_unit(
name: impl Into<String>,
value: f64,
unit: impl Into<String>,
quantity_type: QuantityType,
) -> Self {
Self {
name: name.into(),
value,
unit: unit.into(),
quantity_type,
}
}
pub fn formatted(&self) -> String {
if self.unit.is_empty() {
format!("{}", self.value)
} else {
format!("{} {}", self.value, self.unit)
}
}
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct LightDistributionPlane {
pub c_angle: f64,
pub gamma_angles: Vec<f64>,
pub intensities: Vec<f64>,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct GoniometricData {
pub name: String,
pub colour_temperature: f64,
pub luminous_flux: f64,
pub emitter_type: String,
pub distribution_type: String,
pub planes: Vec<LightDistributionPlane>,
}
pub trait PropertyReader: Send + Sync {
fn property_sets(&self, id: EntityId) -> Vec<PropertySet>;
fn quantities(&self, id: EntityId) -> Vec<Quantity>;
fn get_property(&self, id: EntityId, name: &str) -> Option<Property> {
self.property_sets(id)
.into_iter()
.flat_map(|pset| pset.properties)
.find(|p| p.name == name)
}
fn get_quantity(&self, id: EntityId, name: &str) -> Option<Quantity> {
self.quantities(id).into_iter().find(|q| q.name == name)
}
fn global_id(&self, id: EntityId) -> Option<String>;
fn name(&self, id: EntityId) -> Option<String>;
fn description(&self, id: EntityId) -> Option<String>;
fn object_type(&self, _id: EntityId) -> Option<String> {
None
}
fn tag(&self, _id: EntityId) -> Option<String> {
None
}
fn goniometric_sources(&self, _id: EntityId) -> Vec<GoniometricData> {
Vec::new()
}
}