homestar_invocation/ipld/
link.rs

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