libipld_core/
link.rs

1//! Typed cid.
2use core::{
3    cmp::Ordering,
4    fmt,
5    hash::{Hash, Hasher},
6    marker::PhantomData,
7    ops::Deref,
8};
9
10use crate::cid::Cid;
11use crate::codec::{Codec, Decode, Encode};
12use crate::error::Result;
13use crate::io::{Read, Seek, Write};
14
15/// Typed cid.
16#[derive(Debug)]
17pub struct Link<T> {
18    cid: Cid,
19    _marker: PhantomData<T>,
20}
21
22impl<T> Link<T> {
23    /// Creates a new `Link`.
24    pub fn new(cid: Cid) -> Self {
25        Self {
26            cid,
27            _marker: PhantomData,
28        }
29    }
30
31    /// Returns a reference to the cid.
32    pub fn cid(&self) -> &Cid {
33        &self.cid
34    }
35}
36
37impl<T> fmt::Display for Link<T> {
38    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
39        self.cid.fmt(f)
40    }
41}
42
43impl<T> Clone for Link<T> {
44    fn clone(&self) -> Self {
45        Self {
46            cid: self.cid,
47            _marker: self._marker,
48        }
49    }
50}
51
52impl<T> Copy for Link<T> {}
53
54impl<T> PartialEq for Link<T> {
55    fn eq(&self, other: &Self) -> bool {
56        self.cid.eq(other.cid())
57    }
58}
59
60impl<T> Eq for Link<T> {}
61
62impl<T> PartialOrd for Link<T> {
63    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
64        Some(self.cid.cmp(other.cid()))
65    }
66}
67
68impl<T> Ord for Link<T> {
69    fn cmp(&self, other: &Self) -> Ordering {
70        self.cid.cmp(other.cid())
71    }
72}
73
74impl<T> Hash for Link<T> {
75    fn hash<H: Hasher>(&self, hasher: &mut H) {
76        Hash::hash(self.cid(), hasher)
77    }
78}
79
80impl<C: Codec, T> Encode<C> for Link<T>
81where
82    Cid: Encode<C>,
83{
84    fn encode<W: Write>(&self, c: C, w: &mut W) -> Result<()> {
85        self.cid().encode(c, w)
86    }
87}
88
89impl<C: Codec, T> Decode<C> for Link<T>
90where
91    Cid: Decode<C>,
92{
93    fn decode<R: Read + Seek>(c: C, r: &mut R) -> Result<Self> {
94        Ok(Self::new(Cid::decode(c, r)?))
95    }
96}
97
98impl<T> Deref for Link<T> {
99    type Target = Cid;
100
101    fn deref(&self) -> &Self::Target {
102        self.cid()
103    }
104}
105
106impl<T> AsRef<Cid> for Link<T> {
107    fn as_ref(&self) -> &Cid {
108        self.cid()
109    }
110}
111
112impl<T> From<Cid> for Link<T> {
113    fn from(cid: Cid) -> Self {
114        Self::new(cid)
115    }
116}