1pub mod store;
24
25use bytes::Bytes;
26use tet_libp2p_core::{PeerId, Multiaddr, multihash::Multihash};
27use std::borrow::Borrow;
28use std::hash::{Hash, Hasher};
29use wasm_timer::Instant;
30
31#[derive(Clone, Debug, PartialEq, Eq, Hash)]
33pub struct Key(Bytes);
34
35impl Key {
36 pub fn new<K: AsRef<[u8]>>(key: &K) -> Self {
38 Key(Bytes::copy_from_slice(key.as_ref()))
39 }
40
41 pub fn to_vec(&self) -> Vec<u8> {
43 Vec::from(&self.0[..])
44 }
45}
46
47impl Borrow<[u8]> for Key {
48 fn borrow(&self) -> &[u8] {
49 &self.0[..]
50 }
51}
52
53impl AsRef<[u8]> for Key {
54 fn as_ref(&self) -> &[u8] {
55 &self.0[..]
56 }
57}
58
59impl From<Vec<u8>> for Key {
60 fn from(v: Vec<u8>) -> Key {
61 Key(Bytes::from(v))
62 }
63}
64
65impl From<Multihash> for Key {
66 fn from(m: Multihash) -> Key {
67 Key::from(m.to_bytes())
68 }
69}
70
71#[derive(Clone, Debug, Eq, PartialEq)]
73pub struct Record {
74 pub key: Key,
76 pub value: Vec<u8>,
78 pub publisher: Option<PeerId>,
80 pub expires: Option<Instant>,
82}
83
84impl Record {
85 pub fn new<K>(key: K, value: Vec<u8>) -> Self
87 where
88 K: Into<Key>
89 {
90 Record {
91 key: key.into(),
92 value,
93 publisher: None,
94 expires: None,
95 }
96 }
97
98 pub fn is_expired(&self, now: Instant) -> bool {
100 self.expires.map_or(false, |t| now >= t)
101 }
102}
103
104#[derive(Clone, Debug)]
111pub struct ProviderRecord {
112 pub key: Key,
114 pub provider: PeerId,
116 pub expires: Option<Instant>,
118 pub addresses: Vec<Multiaddr>
120}
121
122impl Hash for ProviderRecord {
123 fn hash<H: Hasher>(&self, state: &mut H) {
124 self.key.hash(state);
125 self.provider.hash(state);
126 }
127}
128
129impl PartialEq for ProviderRecord {
130 fn eq(&self, other: &Self) -> bool {
131 self.key == other.key && self.provider == other.provider
132 }
133}
134
135impl Eq for ProviderRecord {}
136
137impl ProviderRecord {
138 pub fn new<K>(key: K, provider: PeerId, addresses: Vec<Multiaddr>) -> Self
140 where
141 K: Into<Key>
142 {
143 ProviderRecord {
144 key: key.into(),
145 provider,
146 expires: None,
147 addresses,
148 }
149 }
150
151 pub fn is_expired(&self, now: Instant) -> bool {
153 self.expires.map_or(false, |t| now >= t)
154 }
155}
156
157#[cfg(test)]
158mod tests {
159 use super::*;
160 use quickcheck::*;
161 use tet_libp2p_core::multihash::Code;
162 use rand::Rng;
163 use std::time::Duration;
164
165 impl Arbitrary for Key {
166 fn arbitrary<G: Gen>(_: &mut G) -> Key {
167 let hash = rand::thread_rng().gen::<[u8; 32]>();
168 Key::from(Multihash::wrap(Code::Sha2_256.into(), &hash).unwrap())
169 }
170 }
171
172 impl Arbitrary for Record {
173 fn arbitrary<G: Gen>(g: &mut G) -> Record {
174 Record {
175 key: Key::arbitrary(g),
176 value: Vec::arbitrary(g),
177 publisher: if g.gen() { Some(PeerId::random()) } else { None },
178 expires: if g.gen() {
179 Some(Instant::now() + Duration::from_secs(g.gen_range(0, 60)))
180 } else {
181 None
182 },
183 }
184 }
185 }
186
187 impl Arbitrary for ProviderRecord {
188 fn arbitrary<G: Gen>(g: &mut G) -> ProviderRecord {
189 ProviderRecord {
190 key: Key::arbitrary(g),
191 provider: PeerId::random(),
192 expires: if g.gen() {
193 Some(Instant::now() + Duration::from_secs(g.gen_range(0, 60)))
194 } else {
195 None
196 },
197 addresses: vec![],
198 }
199 }
200 }
201}