use std::fmt::{self, Display};
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
pub struct ObjectId {
pub namespace: String,
pub name: String,
}
impl ObjectId {
pub fn new(namespace: String, name: String) -> ObjectId {
ObjectId { namespace, name }
}
pub fn as_id_ref(&self) -> ObjectIdRef {
ObjectIdRef {
namespace: &self.namespace,
name: &self.name,
}
}
pub fn namespace(&self) -> Option<&str> {
self.as_id_ref().namespace()
}
pub fn name(&self) -> &str {
self.name.as_str()
}
}
impl Display for ObjectId {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.as_id_ref().fmt(f)
}
}
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
pub struct ObjectIdRef<'a> {
pub namespace: &'a str,
pub name: &'a str,
}
impl<'a> ObjectIdRef<'a> {
pub fn new(namespace: &'a str, name: &'a str) -> ObjectIdRef<'a> {
ObjectIdRef { namespace, name }
}
pub fn to_owned(&self) -> ObjectId {
ObjectId {
namespace: self.namespace.to_owned(),
name: self.name.to_owned(),
}
}
pub fn namespace(&self) -> Option<&'a str> {
if self.namespace.is_empty() {
None
} else {
Some(self.namespace)
}
}
pub fn name(&self) -> &'a str {
self.name
}
}
impl<'a> Display for ObjectIdRef<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}/{}", self.namespace, self.name)
}
}
impl<'a> PartialEq<ObjectIdRef<'a>> for ObjectId {
fn eq(&self, other: &ObjectIdRef<'a>) -> bool {
self.namespace == other.namespace && self.name == other.name
}
}
impl<'a> PartialEq<ObjectId> for ObjectIdRef<'a> {
fn eq(&self, other: &ObjectId) -> bool {
self.namespace == other.namespace && self.name == other.name
}
}
impl<'a> From<&'a ObjectId> for ObjectIdRef<'a> {
fn from(id: &'a ObjectId) -> ObjectIdRef<'a> {
id.as_id_ref()
}
}
impl<'a> From<(&'a str, &'a str)> for ObjectIdRef<'a> {
fn from((namespace, name): (&'a str, &'a str)) -> ObjectIdRef<'a> {
ObjectIdRef { namespace, name }
}
}
impl<'a, 'b> From<&'b ObjectIdRef<'a>> for ObjectIdRef<'a> {
fn from(other: &'b ObjectIdRef<'a>) -> ObjectIdRef<'a> {
other.clone()
}
}
#[cfg(test)]
mod test {
use super::*;
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
#[test]
fn object_id_has_same_hash_as_ref() {
let id = ObjectId {
namespace: "foo".to_string(),
name: "bar".to_string(),
};
let id_ref = id.as_id_ref();
assert_eq!(hash(&id), hash(&id_ref));
assert_eq!(&id, &id_ref);
}
fn hash<T: Hash>(obj: &T) -> u64 {
let mut hasher = DefaultHasher::new();
obj.hash(&mut hasher);
hasher.finish()
}
}