use std::fmt;
use serde::{Deserialize, Serialize};
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
pub enum PropertyType {
Boolean,
Integer,
Text,
}
#[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
pub enum PropertyValue {
Boolean(bool),
Integer(i64),
Text(String),
}
impl PropertyValue {
#[must_use]
pub const fn value_type(&self) -> PropertyType {
match self {
Self::Boolean(_value) => PropertyType::Boolean,
Self::Integer(_value) => PropertyType::Integer,
Self::Text(_value) => PropertyType::Text,
}
}
}
impl fmt::Display for PropertyValue {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Boolean(value) => write!(formatter, "{value}"),
Self::Integer(value) => write!(formatter, "{value}"),
Self::Text(value) => formatter.write_str(value),
}
}
}
pub(crate) fn parse_value_token(token: &str) -> Result<PropertyValue, String> {
let trimmed = token.trim();
if trimmed == "true" {
return Ok(PropertyValue::Boolean(true));
}
if trimmed == "false" {
return Ok(PropertyValue::Boolean(false));
}
if let Ok(value) = trimmed.parse::<i64>() {
return Ok(PropertyValue::Integer(value));
}
parse_quoted(trimmed).map(PropertyValue::Text)
}
fn parse_quoted(token: &str) -> Result<String, String> {
let single = token
.strip_prefix('\'')
.and_then(|text| text.strip_suffix('\''));
let double = token
.strip_prefix('"')
.and_then(|text| text.strip_suffix('"'));
single
.or(double)
.map_or_else(|| Err(token.to_owned()), |value| Ok(value.to_owned()))
}