bee_block/address/
ed25519.rs

1// Copyright 2020-2021 IOTA Stiftung
2// SPDX-License-Identifier: Apache-2.0
3
4use core::str::FromStr;
5
6use crypto::signatures::ed25519::PUBLIC_KEY_LENGTH;
7use derive_more::{AsRef, Deref, From};
8
9use crate::Error;
10
11/// An Ed25519 address.
12#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, From, AsRef, Deref, packable::Packable)]
13#[as_ref(forward)]
14pub struct Ed25519Address([u8; Self::LENGTH]);
15
16impl Ed25519Address {
17    /// The [`Address`](crate::address::Address) kind of an [`Ed25519Address`].
18    pub const KIND: u8 = 0;
19    /// The length of an [`Ed25519Address`].
20    pub const LENGTH: usize = PUBLIC_KEY_LENGTH;
21
22    /// Creates a new [`Ed25519Address`].
23    #[inline(always)]
24    pub fn new(address: [u8; Self::LENGTH]) -> Self {
25        Self::from(address)
26    }
27}
28
29#[cfg(feature = "serde")]
30string_serde_impl!(Ed25519Address);
31
32impl FromStr for Ed25519Address {
33    type Err = Error;
34
35    fn from_str(s: &str) -> Result<Self, Self::Err> {
36        Ok(Ed25519Address::new(prefix_hex::decode(s).map_err(Error::HexError)?))
37    }
38}
39
40impl core::fmt::Display for Ed25519Address {
41    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
42        write!(f, "{}", prefix_hex::encode(self.0))
43    }
44}
45
46impl core::fmt::Debug for Ed25519Address {
47    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
48        write!(f, "Ed25519Address({})", self)
49    }
50}
51
52#[cfg(feature = "dto")]
53#[allow(missing_docs)]
54pub mod dto {
55    use serde::{Deserialize, Serialize};
56
57    use super::*;
58    use crate::error::dto::DtoError;
59
60    /// Describes an Ed25519 address.
61    #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
62    pub struct Ed25519AddressDto {
63        #[serde(rename = "type")]
64        pub kind: u8,
65        #[serde(rename = "pubKeyHash")]
66        pub pub_key_hash: String,
67    }
68
69    impl From<&Ed25519Address> for Ed25519AddressDto {
70        fn from(value: &Ed25519Address) -> Self {
71            Self {
72                kind: Ed25519Address::KIND,
73                pub_key_hash: value.to_string(),
74            }
75        }
76    }
77
78    impl TryFrom<&Ed25519AddressDto> for Ed25519Address {
79        type Error = DtoError;
80
81        fn try_from(value: &Ed25519AddressDto) -> Result<Self, Self::Error> {
82            value
83                .pub_key_hash
84                .parse::<Ed25519Address>()
85                .map_err(|_| DtoError::InvalidField("Ed25519 address"))
86        }
87    }
88}