1use std::path::PathBuf;
20use tinyjson::JsonValue;
21
22use darkfi::{
23 geode::hash_to_string,
24 rpc::util::{json_map, json_str},
25};
26
27use crate::resource::Resource;
28
29#[derive(Clone, Debug)]
30pub struct DownloadStarted {
31 pub hash: blake3::Hash,
32 pub resource: Resource,
33}
34#[derive(Clone, Debug)]
35pub struct ChunkDownloadCompleted {
36 pub hash: blake3::Hash,
37 pub chunk_hash: blake3::Hash,
38 pub resource: Resource,
39}
40#[derive(Clone, Debug)]
41pub struct MetadataDownloadCompleted {
42 pub hash: blake3::Hash,
43 pub resource: Resource,
44}
45#[derive(Clone, Debug)]
46pub struct DownloadCompleted {
47 pub hash: blake3::Hash,
48 pub resource: Resource,
49}
50#[derive(Clone, Debug)]
51pub struct ResourceUpdated {
52 pub hash: blake3::Hash,
53 pub resource: Resource,
54}
55#[derive(Clone, Debug)]
56pub struct ResourceRemoved {
57 pub hash: blake3::Hash,
58}
59#[derive(Clone, Debug)]
60pub struct ChunkNotFound {
61 pub hash: blake3::Hash,
62 pub chunk_hash: blake3::Hash,
63}
64#[derive(Clone, Debug)]
65pub struct MetadataNotFound {
66 pub hash: blake3::Hash,
67 pub resource: Resource,
68}
69#[derive(Clone, Debug)]
70pub struct MissingChunks {
71 pub hash: blake3::Hash,
72 pub resource: Resource,
73}
74#[derive(Clone, Debug)]
75pub struct DownloadError {
76 pub hash: blake3::Hash,
77 pub error: String,
78}
79#[derive(Clone, Debug)]
80pub struct InsertCompleted {
81 pub hash: blake3::Hash,
82 pub path: PathBuf,
83}
84#[derive(Clone, Debug)]
85pub struct InsertError {
86 pub path: PathBuf,
87 pub error: String,
88}
89
90#[derive(Clone, Debug)]
91pub enum FudEvent {
92 DownloadStarted(DownloadStarted),
93 ChunkDownloadCompleted(ChunkDownloadCompleted),
94 MetadataDownloadCompleted(MetadataDownloadCompleted),
95 DownloadCompleted(DownloadCompleted),
96 ResourceUpdated(ResourceUpdated),
97 ResourceRemoved(ResourceRemoved),
98 ChunkNotFound(ChunkNotFound),
99 MetadataNotFound(MetadataNotFound),
100 MissingChunks(MissingChunks),
101 DownloadError(DownloadError),
102 InsertCompleted(InsertCompleted),
103 InsertError(InsertError),
104}
105
106impl From<DownloadStarted> for JsonValue {
107 fn from(info: DownloadStarted) -> JsonValue {
108 json_map([
109 ("hash", JsonValue::String(hash_to_string(&info.hash))),
110 ("resource", info.resource.into()),
111 ])
112 }
113}
114impl From<ChunkDownloadCompleted> for JsonValue {
115 fn from(info: ChunkDownloadCompleted) -> JsonValue {
116 json_map([
117 ("hash", JsonValue::String(hash_to_string(&info.hash))),
118 ("chunk_hash", JsonValue::String(hash_to_string(&info.chunk_hash))),
119 ("resource", info.resource.into()),
120 ])
121 }
122}
123impl From<MetadataDownloadCompleted> for JsonValue {
124 fn from(info: MetadataDownloadCompleted) -> JsonValue {
125 json_map([
126 ("hash", JsonValue::String(hash_to_string(&info.hash))),
127 ("resource", info.resource.into()),
128 ])
129 }
130}
131impl From<DownloadCompleted> for JsonValue {
132 fn from(info: DownloadCompleted) -> JsonValue {
133 json_map([
134 ("hash", JsonValue::String(hash_to_string(&info.hash))),
135 ("resource", info.resource.into()),
136 ])
137 }
138}
139impl From<ResourceUpdated> for JsonValue {
140 fn from(info: ResourceUpdated) -> JsonValue {
141 json_map([
142 ("hash", JsonValue::String(hash_to_string(&info.hash))),
143 ("resource", info.resource.into()),
144 ])
145 }
146}
147impl From<ResourceRemoved> for JsonValue {
148 fn from(info: ResourceRemoved) -> JsonValue {
149 json_map([("hash", JsonValue::String(hash_to_string(&info.hash)))])
150 }
151}
152impl From<ChunkNotFound> for JsonValue {
153 fn from(info: ChunkNotFound) -> JsonValue {
154 json_map([
155 ("hash", JsonValue::String(hash_to_string(&info.hash))),
156 ("chunk_hash", JsonValue::String(hash_to_string(&info.chunk_hash))),
157 ])
158 }
159}
160impl From<MetadataNotFound> for JsonValue {
161 fn from(info: MetadataNotFound) -> JsonValue {
162 json_map([
163 ("hash", JsonValue::String(hash_to_string(&info.hash))),
164 ("resource", info.resource.into()),
165 ])
166 }
167}
168impl From<MissingChunks> for JsonValue {
169 fn from(info: MissingChunks) -> JsonValue {
170 json_map([
171 ("hash", JsonValue::String(hash_to_string(&info.hash))),
172 ("resource", info.resource.into()),
173 ])
174 }
175}
176impl From<DownloadError> for JsonValue {
177 fn from(info: DownloadError) -> JsonValue {
178 json_map([
179 ("hash", JsonValue::String(hash_to_string(&info.hash))),
180 ("error", JsonValue::String(info.error)),
181 ])
182 }
183}
184impl From<InsertCompleted> for JsonValue {
185 fn from(info: InsertCompleted) -> JsonValue {
186 json_map([
187 ("hash", JsonValue::String(hash_to_string(&info.hash))),
188 ("path", JsonValue::String(info.path.to_string_lossy().to_string())),
189 ])
190 }
191}
192impl From<InsertError> for JsonValue {
193 fn from(info: InsertError) -> JsonValue {
194 json_map([
195 ("path", JsonValue::String(info.path.to_string_lossy().to_string())),
196 ("error", JsonValue::String(info.error)),
197 ])
198 }
199}
200impl From<FudEvent> for JsonValue {
201 fn from(event: FudEvent) -> JsonValue {
202 match event {
203 FudEvent::DownloadStarted(info) => {
204 json_map([("event", json_str("download_started")), ("info", info.into())])
205 }
206 FudEvent::ChunkDownloadCompleted(info) => {
207 json_map([("event", json_str("chunk_download_completed")), ("info", info.into())])
208 }
209 FudEvent::MetadataDownloadCompleted(info) => json_map([
210 ("event", json_str("metadata_download_completed")),
211 ("info", info.into()),
212 ]),
213 FudEvent::DownloadCompleted(info) => {
214 json_map([("event", json_str("download_completed")), ("info", info.into())])
215 }
216 FudEvent::ResourceUpdated(info) => {
217 json_map([("event", json_str("resource_updated")), ("info", info.into())])
218 }
219 FudEvent::ResourceRemoved(info) => {
220 json_map([("event", json_str("resource_removed")), ("info", info.into())])
221 }
222 FudEvent::ChunkNotFound(info) => {
223 json_map([("event", json_str("chunk_not_found")), ("info", info.into())])
224 }
225 FudEvent::MetadataNotFound(info) => {
226 json_map([("event", json_str("metadata_not_found")), ("info", info.into())])
227 }
228 FudEvent::MissingChunks(info) => {
229 json_map([("event", json_str("missing_chunks")), ("info", info.into())])
230 }
231 FudEvent::DownloadError(info) => {
232 json_map([("event", json_str("download_error")), ("info", info.into())])
233 }
234 FudEvent::InsertCompleted(info) => {
235 json_map([("event", json_str("insert_completed")), ("info", info.into())])
236 }
237 FudEvent::InsertError(info) => {
238 json_map([("event", json_str("insert_error")), ("info", info.into())])
239 }
240 }
241 }
242}
243
244macro_rules! notify_event {
246 ($fud:ident, $event:ident, { $($fields:tt)* }) => {
248 $fud
249 .event_publisher
250 .notify(FudEvent::$event(event::$event {
251 $($fields)*
252 }))
253 .await;
254 };
255 ($fud:ident, $event:ident, $resource:expr) => {
257 $fud
258 .event_publisher
259 .notify(FudEvent::$event(event::$event {
260 hash: $resource.hash,
261 resource: $resource.clone(),
262 }))
263 .await;
264 };
265}
266pub(crate) use notify_event;