Implementing it all (hopefully correctly), yields a binary size increase:
artifact | size in bytes |
---|---|
before | 1,042,511 |
after | 1,056,747 |
#[derive(Deserialize, Serialize)]
pub struct WrappedId<Tag>(
Uuid,
PhantomData<Tag>,
);
impl<Tag> Clone for WrappedId<Tag> {
fn clone(&self) -> Self {
Self(self.0.clone(), PhantomData)
}
}
impl<Tag> Copy for WrappedId<Tag> {}
impl<Tag> PartialEq for WrappedId<Tag> {
fn eq(&self, other: &Self) -> bool {
self.0.eq(&other.0)
}
}
impl<Tag> Hash for WrappedId<Tag> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.0.hash(state);
}
}
impl<Tag> PartialOrd for WrappedId<Tag> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.0.partial_cmp(&other.0)
}
}
impl<Tag> Ord for WrappedId<Tag> {
fn cmp(&self, other: &Self) -> Ordering {
self.0.cmp(&other.0)
}
}
impl<Tag> Eq for WrappedId<Tag> {}
impl<Tag> Debug for WrappedId<Tag> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "WrappedId({})", self.0)
}
}
impl<Tag> WrappedId<Tag> {
fn new(uuid: Uuid) -> WrappedId<Tag> {
Self(uuid, PhantomData)
}
}
impl<Tag> fmt::Display for WrappedId<Tag> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
std::fmt::Display::fmt(&self.0, f)
}
}
impl<Tag> From<Uuid> for WrappedId<Tag> {
fn from(id: Uuid) -> Self {
WrappedId::new(id)
}
}
impl<Tag> FromStr for WrappedId<Tag> {
type Err = uuid::Error;
fn from_str(value: &str) -> Result<WrappedId<Tag>, uuid::Error> {
match Uuid::parse_str(value) {
Ok(id) => Ok(id.into()),
Err(e) => Err(e),
}
}
}
impl<Tag> From<WrappedId<Tag>> for Uuid {
fn from(n: WrappedId<Tag>) -> Uuid {
n.0
}
}
impl<Tag> Deref for WrappedId<Tag> {
type Target = Uuid;
fn deref(&self) -> &Self::Target {
&self.0
}
}
macro_rules! make_id {
($name:ident, $tag:ident) => {
pub struct $tag;
pub type $name = WrappedId<$tag>;
};
}
// Lots and lots of make_id! after here