Skip to main content

monero_lws/
util.rs

1// Rust Monero Light Wallet Server RPC Client
2// Written in 2021-2022 by
3//   Sebastian Kung <seb.kung@gmail.com>
4//   Monero Rust Contributors
5//
6// Permission is hereby granted, free of charge, to any person obtaining a copy
7// of this software and associated documentation files (the "Software"), to deal
8// in the Software without restriction, including without limitation the rights
9// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10// copies of the Software, and to permit persons to whom the Software is
11// furnished to do so, subject to the following conditions:
12//
13// The above copyright notice and this permission notice shall be included in all
14// copies or substantial portions of the Software.
15//
16
17use serde::{Deserialize, Deserializer, Serialize};
18use std::fmt::{self, Display};
19
20pub trait HashType: Sized {
21    fn bytes(&self) -> &[u8];
22    fn from_str(v: &str) -> anyhow::Result<Self>;
23}
24
25macro_rules! hash_type_impl {
26    ($name:ty) => {
27        impl HashType for $name {
28            fn bytes(&self) -> &[u8] {
29                self.as_bytes()
30            }
31            fn from_str(v: &str) -> anyhow::Result<Self> {
32                Ok(v.parse()?)
33            }
34        }
35    };
36}
37
38hash_type_impl!(monero::util::address::PaymentId);
39hash_type_impl!(monero::cryptonote::hash::Hash);
40
41impl HashType for Vec<u8> {
42    fn bytes(&self) -> &[u8] {
43        self
44    }
45    fn from_str(v: &str) -> anyhow::Result<Self> {
46        Ok(hex::decode(v)?)
47    }
48}
49
50#[derive(Clone, Debug)]
51pub struct HashString<T>(pub T);
52
53impl<T> Display for HashString<T>
54where
55    T: HashType,
56{
57    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
58        write!(f, "{}", hex::encode(self.0.bytes()))
59    }
60}
61
62impl<T> Serialize for HashString<T>
63where
64    T: HashType,
65{
66    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
67    where
68        S: serde::ser::Serializer,
69    {
70        serializer.serialize_str(&self.to_string())
71    }
72}
73
74impl<'de, T> Deserialize<'de> for HashString<T>
75where
76    T: HashType,
77{
78    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
79    where
80        D: Deserializer<'de>,
81    {
82        let s = String::deserialize(deserializer)?;
83        Ok(Self(T::from_str(&s).map_err(serde::de::Error::custom)?))
84    }
85}