1
2use std::borrow::Borrow;
3
4use bitcoin::hex::FromHex;
5use log::debug;
6
7
8pub trait StatusExt: Borrow<tonic::Status> {
10 fn is_rejection(&self) -> bool;
12
13 fn not_found<T: FromHex>(&self) -> Option<Vec<T>>;
15}
16
17impl StatusExt for tonic::Status {
18 fn is_rejection(&self) -> bool {
19 match self.code() {
20 tonic::Code::InvalidArgument | tonic::Code::NotFound => true,
21 _ => false,
22 }
23 }
24
25 fn not_found<T: FromHex>(&self) -> Option<Vec<T>> {
26 if self.code() != tonic::Code::NotFound {
27 return None;
28 }
29
30 let ids = match self.metadata().get("identifiers") {
31 Some(v) => v,
32 None => {
33 debug!("Server sent NOT_FOUND error without identifiers");
34 return Some(vec![]);
35 },
36 };
37 let mut ret = Vec::new();
38 let ids_str = match ids.to_str() {
39 Ok(v) => v,
40 Err(e) => {
41 debug!("Invalid (non-ASCII) value in NOT_FOUND identifiers metadata: {:#}", e);
42 return Some(vec![]);
43 },
44 };
45 for value in ids_str.split(',') {
46 match T::from_hex(value) {
47 Ok(v) => ret.push(v),
48 Err(e) => {
49 debug!("Server NOT_FOUND identifier could not be parsed: {:#}", e);
50 },
51 }
52 }
53 Some(ret)
54 }
55}