use std::{
borrow::Cow,
fmt::Display,
marker::PhantomData,
ops::{Deref, DerefMut},
};
use url::Url;
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ObjectId<'a, Kind> {
url: Cow<'a, Url>,
_kind: PhantomData<fn() -> Kind>,
}
impl<'a, Kind> Clone for ObjectId<'a, Kind> {
fn clone(&self) -> Self {
Self {
url: self.url.clone(),
_kind: PhantomData,
}
}
}
impl<Kind> ObjectId<'static, Kind> {
pub fn new_owned(url: Url) -> Self {
Self {
url: Cow::Owned(url),
_kind: PhantomData,
}
}
}
impl<'a, Kind> ObjectId<'a, Kind> {
pub fn new_borrowed(url: &'a Url) -> Self {
Self {
url: Cow::Borrowed(url),
_kind: PhantomData,
}
}
}
impl<'a, Kind> Deref for ObjectId<'a, Kind> {
type Target = Url;
fn deref(&self) -> &Self::Target {
&self.url
}
}
impl<'a, Kind> DerefMut for ObjectId<'a, Kind> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.url.to_mut()
}
}
impl<'a, Kind> Display for ObjectId<'a, Kind> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.url.fmt(f)
}
}
impl<'a, Kind> serde::ser::Serialize for ObjectId<'a, Kind> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
self.url.serialize(serializer)
}
}
impl<'de, Kind> serde::de::Deserialize<'de> for ObjectId<'static, Kind> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
Url::deserialize(deserializer).map(ObjectId::new_owned)
}
}