Skip to content

Commit 789730e

Browse files
authored
Merge pull request #133 from stevenroose/hex-serde-pubkey
Implement hex human-readable serde for PublicKey
2 parents 84345f2 + 0f25474 commit 789730e

File tree

1 file changed

+72
-7
lines changed

1 file changed

+72
-7
lines changed

src/key.rs

Lines changed: 72 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ pub struct SecretKey([u8; constants::SECRET_KEY_SIZE]);
3131
impl_array_newtype!(SecretKey, u8, constants::SECRET_KEY_SIZE);
3232
impl_pretty_debug!(SecretKey);
3333

34-
impl fmt::Display for SecretKey {
34+
impl fmt::LowerHex for SecretKey {
3535
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3636
for ch in &self.0[..] {
3737
write!(f, "{:02x}", *ch)?;
@@ -40,6 +40,12 @@ impl fmt::Display for SecretKey {
4040
}
4141
}
4242

43+
impl fmt::Display for SecretKey {
44+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
45+
fmt::LowerHex::fmt(self, f)
46+
}
47+
}
48+
4349
impl str::FromStr for SecretKey {
4450
type Err = Error;
4551
fn from_str(s: &str) -> Result<SecretKey, Error> {
@@ -61,7 +67,7 @@ pub const ONE_KEY: SecretKey = SecretKey([0, 0, 0, 0, 0, 0, 0, 0,
6167
#[derive(Copy, Clone, PartialEq, Eq, Debug, PartialOrd, Ord, Hash)]
6268
pub struct PublicKey(ffi::PublicKey);
6369

64-
impl fmt::Display for PublicKey {
70+
impl fmt::LowerHex for PublicKey {
6571
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6672
let ser = self.serialize();
6773
for ch in &ser[..] {
@@ -71,6 +77,12 @@ impl fmt::Display for PublicKey {
7177
}
7278
}
7379

80+
impl fmt::Display for PublicKey {
81+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
82+
fmt::LowerHex::fmt(self, f)
83+
}
84+
}
85+
7486
impl str::FromStr for PublicKey {
7587
type Err = Error;
7688
fn from_str(s: &str) -> Result<PublicKey, Error> {
@@ -354,17 +366,66 @@ impl From<ffi::PublicKey> for PublicKey {
354366
#[cfg(feature = "serde")]
355367
impl ::serde::Serialize for PublicKey {
356368
fn serialize<S: ::serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
357-
s.serialize_bytes(&self.serialize())
369+
if s.is_human_readable() {
370+
s.collect_str(self)
371+
} else {
372+
s.serialize_bytes(&self.serialize())
373+
}
358374
}
359375
}
360376

361377
#[cfg(feature = "serde")]
362378
impl<'de> ::serde::Deserialize<'de> for PublicKey {
363379
fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> Result<PublicKey, D::Error> {
364-
use ::serde::de::Error;
380+
if d.is_human_readable() {
381+
struct HexVisitor;
382+
383+
impl<'de> ::serde::de::Visitor<'de> for HexVisitor {
384+
type Value = PublicKey;
385+
386+
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
387+
formatter.write_str("an ASCII hex string")
388+
}
389+
390+
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
391+
where
392+
E: ::serde::de::Error,
393+
{
394+
if let Ok(hex) = str::from_utf8(v) {
395+
str::FromStr::from_str(hex).map_err(E::custom)
396+
} else {
397+
Err(E::invalid_value(::serde::de::Unexpected::Bytes(v), &self))
398+
}
399+
}
400+
401+
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
402+
where
403+
E: ::serde::de::Error,
404+
{
405+
str::FromStr::from_str(v).map_err(E::custom)
406+
}
407+
}
408+
d.deserialize_str(HexVisitor)
409+
} else {
410+
struct BytesVisitor;
411+
412+
impl<'de> ::serde::de::Visitor<'de> for BytesVisitor {
413+
type Value = PublicKey;
365414

366-
let sl: &[u8] = ::serde::Deserialize::deserialize(d)?;
367-
PublicKey::from_slice(sl).map_err(D::Error::custom)
415+
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
416+
formatter.write_str("a bytestring")
417+
}
418+
419+
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
420+
where
421+
E: ::serde::de::Error,
422+
{
423+
PublicKey::from_slice(v).map_err(E::custom)
424+
}
425+
}
426+
427+
d.deserialize_bytes(BytesVisitor)
428+
}
368429
}
369430
}
370431

@@ -733,6 +794,9 @@ mod test {
733794
0x06, 0x83, 0x7f, 0x30, 0xaa, 0x0c, 0xd0, 0x54,
734795
0x4a, 0xc8, 0x87, 0xfe, 0x91, 0xdd, 0xd1, 0x66,
735796
];
797+
static PK_STR: &'static str = "\
798+
0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166\
799+
";
736800

737801
let s = Secp256k1::new();
738802

@@ -741,6 +805,7 @@ mod test {
741805

742806
assert_tokens(&sk.compact(), &[Token::BorrowedBytes(&SK_BYTES[..])]);
743807
assert_tokens(&sk.readable(), &[Token::BorrowedStr(SK_STR)]);
744-
assert_tokens(&pk, &[Token::BorrowedBytes(&PK_BYTES[..])]);
808+
assert_tokens(&pk.compact(), &[Token::BorrowedBytes(&PK_BYTES[..])]);
809+
assert_tokens(&pk.readable(), &[Token::BorrowedStr(PK_STR)]);
745810
}
746811
}

0 commit comments

Comments
 (0)