bip32: Add serde for Extended(Priv|Pub)Key

This commit is contained in:
Steven Roose 2019-05-28 14:06:32 +01:00
parent c93a70487f
commit 3c66418f3a
No known key found for this signature in database
GPG Key ID: 2F2A88D7F8D68E87
3 changed files with 61 additions and 94 deletions

View File

@ -400,6 +400,63 @@ macro_rules! serde_struct_impl {
)
}
macro_rules! serde_string_impl {
($name:ident, $expecting:expr) => {
#[cfg(feature = "serde")]
impl<'de> $crate::serde::Deserialize<'de> for $name {
fn deserialize<D>(deserializer: D) -> Result<$name, D::Error>
where
D: $crate::serde::de::Deserializer<'de>,
{
use std::fmt::{self, Formatter};
use std::str::FromStr;
struct Visitor;
impl<'de> $crate::serde::de::Visitor<'de> for Visitor {
type Value = $name;
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
formatter.write_str($expecting)
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: $crate::serde::de::Error,
{
$name::from_str(v).map_err(E::custom)
}
fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
where
E: $crate::serde::de::Error,
{
self.visit_str(v)
}
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
where
E: $crate::serde::de::Error,
{
self.visit_str(&v)
}
}
deserializer.deserialize_str(Visitor)
}
}
#[cfg(feature = "serde")]
impl<'de> $crate::serde::Serialize for $name {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: $crate::serde::Serializer,
{
serializer.serialize_str(&self.to_string())
}
}
};
}
macro_rules! user_enum {
(
$(#[$attr:meta])*

View File

@ -46,9 +46,6 @@ use std::str::FromStr;
use bitcoin_bech32::{self, WitnessProgram, u5};
use bitcoin_hashes::{hash160, Hash};
#[cfg(feature = "serde")]
use serde;
use blockdata::opcodes;
use blockdata::script;
use network::constants::Network;
@ -75,6 +72,7 @@ pub struct Address {
/// The network on which this address is usable
pub network: Network,
}
serde_string_impl!(Address, "a Bitcoin address");
impl Address {
/// Creates a pay to (compressed) public key hash address from a public key
@ -299,59 +297,6 @@ impl ::std::fmt::Debug for Address {
}
}
#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for Address {
#[inline]
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
use std::fmt::{self, Formatter};
struct Visitor;
impl<'de> serde::de::Visitor<'de> for Visitor {
type Value = Address;
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
formatter.write_str("a Bitcoin address")
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Address::from_str(v).map_err(E::custom)
}
fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_str(v)
}
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_str(&v)
}
}
deserializer.deserialize_str(Visitor)
}
}
#[cfg(feature = "serde")]
impl serde::Serialize for Address {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(&self.to_string())
}
}
#[cfg(test)]
mod tests {
use std::str::FromStr;

View File

@ -62,6 +62,7 @@ pub struct ExtendedPrivKey {
/// Chain code
pub chain_code: ChainCode
}
serde_string_impl!(ExtendedPrivKey, "a BIP-32 extended private key");
/// Extended public key
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
@ -79,6 +80,7 @@ pub struct ExtendedPubKey {
/// Chain code
pub chain_code: ChainCode
}
serde_string_impl!(ExtendedPubKey, "a BIP-32 extended public key");
/// A child number for a derived key
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
@ -213,6 +215,7 @@ impl serde::Serialize for ChildNumber {
#[derive(Clone, PartialEq, Eq)]
pub struct DerivationPath(Vec<ChildNumber>);
impl_index_newtype!(DerivationPath, ChildNumber);
serde_string_impl!(DerivationPath, "a BIP-32 derivation path");
impl From<Vec<ChildNumber>> for DerivationPath {
fn from(numbers: Vec<ChildNumber>) -> Self {
@ -349,44 +352,6 @@ impl fmt::Debug for DerivationPath {
}
}
#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for DerivationPath {
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
use std::fmt;
use serde::de;
struct Visitor;
impl<'de> de::Visitor<'de> for Visitor {
type Value = DerivationPath;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a Bitcoin address")
}
fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
DerivationPath::from_str(v).map_err(E::custom)
}
fn visit_borrowed_str<E: de::Error>(self, v: &'de str) -> Result<Self::Value, E> {
self.visit_str(v)
}
fn visit_string<E: de::Error>(self, v: String) -> Result<Self::Value, E> {
self.visit_str(&v)
}
}
deserializer.deserialize_str(Visitor)
}
}
#[cfg(feature = "serde")]
impl serde::Serialize for DerivationPath {
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(&self.to_string())
}
}
/// A BIP32 error
#[derive(Clone, PartialEq, Eq, Debug)]
pub enum Error {