use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct Metadata {
pub width: u32,
pub height: u32,
pub is_organized: bool,
pub sensor_origin: [f32; 3],
pub sensor_orientation: [f32; 4],
pub custom_fields: std::collections::HashMap<String, String>,
}
impl Metadata {
pub fn new_unorganized(point_count: usize) -> Self {
Self {
width: point_count as u32,
height: 1,
is_organized: false,
sensor_origin: [0.0, 0.0, 0.0],
sensor_orientation: [1.0, 0.0, 0.0, 0.0], custom_fields: std::collections::HashMap::new(),
}
}
pub fn new_organized(width: u32, height: u32) -> Self {
Self {
width,
height,
is_organized: true,
sensor_origin: [0.0, 0.0, 0.0],
sensor_orientation: [1.0, 0.0, 0.0, 0.0], custom_fields: std::collections::HashMap::new(),
}
}
pub fn point_count(&self) -> usize {
(self.width * self.height) as usize
}
pub fn with_sensor_origin(mut self, origin: [f32; 3]) -> Self {
self.sensor_origin = origin;
self
}
pub fn with_sensor_orientation(mut self, orientation: [f32; 4]) -> Self {
self.sensor_orientation = orientation;
self
}
pub fn with_custom_field<K, V>(mut self, key: K, value: V) -> Self
where
K: Into<String>,
V: Into<String>,
{
self.custom_fields.insert(key.into(), value.into());
self
}
pub fn get_custom_field(&self, key: &str) -> Option<&String> {
self.custom_fields.get(key)
}
pub fn is_dense(&self) -> bool {
self.custom_fields
.get("dense")
.map(|v| v == "true")
.unwrap_or(true)
}
pub fn set_dense(&mut self, dense: bool) {
self.custom_fields
.insert("dense".to_string(), dense.to_string());
}
}
impl Default for Metadata {
fn default() -> Self {
Self::new_unorganized(0)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_metadata_creation() {
let meta = Metadata::new_unorganized(1000);
assert_eq!(meta.width, 1000);
assert_eq!(meta.height, 1);
assert!(!meta.is_organized);
assert_eq!(meta.point_count(), 1000);
}
#[test]
fn test_organized_metadata() {
let meta = Metadata::new_organized(640, 480);
assert_eq!(meta.width, 640);
assert_eq!(meta.height, 480);
assert!(meta.is_organized);
assert_eq!(meta.point_count(), 640 * 480);
}
#[test]
fn test_custom_fields() {
let meta = Metadata::new_unorganized(100)
.with_custom_field("source", "kinect")
.with_custom_field("timestamp", "2023-01-01");
assert_eq!(meta.get_custom_field("source"), Some(&"kinect".to_string()));
assert_eq!(
meta.get_custom_field("timestamp"),
Some(&"2023-01-01".to_string())
);
assert_eq!(meta.get_custom_field("nonexistent"), None);
}
}