use std::fmt;
#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct Symbol(pub String);
impl fmt::Debug for Symbol {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("Symbol").field(&self.0).finish()
}
}
impl fmt::Display for Symbol {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(Clone, PartialEq)]
pub struct RangeValue {
pub lower: Option<f64>,
pub upper: Option<f64>,
}
impl fmt::Debug for RangeValue {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("RangeValue")
.field("lower", &self.lower)
.field("upper", &self.upper)
.finish()
}
}
impl fmt::Display for RangeValue {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match (self.lower, self.upper) {
(Some(lower), Some(upper)) => write!(f, "{}..{}", lower, upper),
(Some(lower), None) => write!(f, "{}..", lower),
(None, Some(upper)) => write!(f, "..{}", upper),
(None, None) => write!(f, ".."),
}
}
}
#[derive(Clone, PartialEq)]
pub enum Value {
VInteger(i64),
VDecimal(f64),
VBoolean(bool),
VString(String),
VSymbol(String),
VTaggedString {
tag: String,
content: String,
},
VArray(Vec<Value>),
VMap(std::collections::HashMap<String, Value>),
VRange(RangeValue),
VMeasurement {
unit: String,
value: f64,
},
}
impl fmt::Debug for Value {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Value::VInteger(i) => f.debug_tuple("VInteger").field(i).finish(),
Value::VDecimal(d) => f.debug_tuple("VDecimal").field(d).finish(),
Value::VBoolean(b) => f.debug_tuple("VBoolean").field(b).finish(),
Value::VString(s) => f.debug_tuple("VString").field(s).finish(),
Value::VSymbol(s) => f.debug_tuple("VSymbol").field(s).finish(),
Value::VTaggedString { tag, content } => f
.debug_struct("VTaggedString")
.field("tag", tag)
.field("content", content)
.finish(),
Value::VArray(arr) => f.debug_list().entries(arr).finish(),
Value::VMap(map) => f.debug_map().entries(map.iter()).finish(),
Value::VRange(r) => f.debug_tuple("VRange").field(r).finish(),
Value::VMeasurement { unit, value } => f
.debug_struct("VMeasurement")
.field("unit", unit)
.field("value", value)
.finish(),
}
}
}
impl fmt::Display for Value {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Value::VInteger(i) => write!(f, "{}", i),
Value::VDecimal(d) => write!(f, "{}", d),
Value::VBoolean(b) => write!(f, "{}", b),
Value::VString(s) => write!(f, "\"{}\"", s),
Value::VSymbol(s) => write!(f, "{}", s),
Value::VTaggedString { tag, content } => write!(f, "{}:{}", tag, content),
Value::VArray(arr) => {
write!(f, "[")?;
for (i, item) in arr.iter().enumerate() {
if i > 0 {
write!(f, ", ")?;
}
write!(f, "{}", item)?;
}
write!(f, "]")
}
Value::VMap(map) => {
write!(f, "{{")?;
let mut first = true;
for (k, v) in map.iter() {
if !first {
write!(f, ", ")?;
}
first = false;
write!(f, "{}: {}", k, v)?;
}
write!(f, "}}")
}
Value::VRange(r) => write!(f, "{}", r),
Value::VMeasurement { unit, value } => write!(f, "{}{}", value, unit),
}
}
}
pub type PropertyRecord = std::collections::HashMap<String, Value>;
#[derive(Clone, PartialEq)]
pub struct Subject {
pub identity: Symbol,
pub labels: std::collections::HashSet<String>,
pub properties: PropertyRecord,
}
impl fmt::Debug for Subject {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Subject")
.field("identity", &self.identity)
.field("labels", &self.labels)
.field("properties", &self.properties)
.finish()
}
}
impl fmt::Display for Subject {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.identity)?;
if !self.labels.is_empty() {
write!(f, ":")?;
let mut labels_vec: Vec<_> = self.labels.iter().collect();
labels_vec.sort();
for (i, label) in labels_vec.iter().enumerate() {
if i > 0 {
write!(f, "::")?;
}
write!(f, "{}", label)?;
}
}
if !self.properties.is_empty() {
write!(f, " {{")?;
let mut props_vec: Vec<_> = self.properties.iter().collect();
props_vec.sort_by_key(|(k, _)| *k);
for (i, (key, value)) in props_vec.iter().enumerate() {
if i > 0 {
write!(f, ", ")?;
}
write!(f, "{}: {}", key, value)?;
}
write!(f, "}}")?;
}
Ok(())
}
}