use crate::haystack::val::Value;
use std::cmp::{Eq, Ord, Ordering, PartialOrd};
use std::fmt;
use std::hash::Hash;
use uuid::Uuid;
#[derive(Eq, Clone, Debug, Default)]
pub struct Ref {
pub value: String,
pub dis: Option<String>,
}
impl Ref {
pub fn make(val: &str, dis: Option<&str>) -> Self {
Ref {
value: val.into(),
dis: dis.map(|s| s.into()),
}
}
pub fn generate() -> Ref {
let uuid = Uuid::new_v4().as_simple().to_string();
Ref {
value: format!("{start}-{end}", start = &uuid[0..8], end = &uuid[26..]),
dis: None,
}
}
pub fn as_str(&self) -> &str {
self.value.as_str()
}
}
impl PartialEq for Ref {
fn eq(&self, other: &Self) -> bool {
self.value == other.value
}
}
#[allow(clippy::non_canonical_partial_ord_impl)]
impl PartialOrd for Ref {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.value.partial_cmp(&other.value)
}
}
impl Ord for Ref {
fn cmp(&self, other: &Self) -> Ordering {
self.value.cmp(&other.value)
}
}
impl fmt::Display for Ref {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "@{}", self.value)
}
}
impl From<&str> for Ref {
fn from(value: &str) -> Self {
Ref {
value: String::from(value),
dis: None,
}
}
}
impl From<String> for Ref {
fn from(value: String) -> Self {
Ref { value, dis: None }
}
}
impl From<Ref> for Value {
fn from(value: Ref) -> Self {
Value::Ref(value)
}
}
impl TryFrom<&Value> for Ref {
type Error = &'static str;
fn try_from(value: &Value) -> Result<Self, Self::Error> {
match value {
Value::Ref(v) => Ok(v.clone()),
_ => Err("Value is not an `Ref`"),
}
}
}
impl Hash for Ref {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.value.hash(state);
}
}