use std::str::FromStr;
use serde::{Deserialize, Serialize};
use crate::IrohError;
#[derive(Debug, Clone, Eq, Serialize, Deserialize, uniffi::Object)]
#[uniffi::export(Display)]
pub struct PublicKey {
pub(crate) key: [u8; 32],
}
impl From<iroh::PublicKey> for PublicKey {
fn from(key: iroh::PublicKey) -> Self {
PublicKey {
key: *key.as_bytes(),
}
}
}
impl From<&PublicKey> for iroh::PublicKey {
fn from(key: &PublicKey) -> Self {
iroh::PublicKey::from_bytes(&key.key).unwrap()
}
}
#[uniffi::export]
impl PublicKey {
pub fn equal(&self, other: &PublicKey) -> bool {
*self == *other
}
pub fn to_bytes(&self) -> Vec<u8> {
self.key.to_vec()
}
#[uniffi::constructor]
pub fn from_string(s: String) -> Result<Self, IrohError> {
let key = iroh::PublicKey::from_str(&s).map_err(anyhow::Error::from)?;
Ok(key.into())
}
#[uniffi::constructor]
pub fn from_bytes(bytes: Vec<u8>) -> Result<Self, IrohError> {
if bytes.len() != 32 {
return Err(anyhow::anyhow!("the PublicKey must be 32 bytes in length").into());
}
let bytes: [u8; 32] = bytes.try_into().expect("checked above");
let key = iroh::PublicKey::from_bytes(&bytes).map_err(anyhow::Error::from)?;
Ok(key.into())
}
pub fn fmt_short(&self) -> String {
iroh::PublicKey::from(self).fmt_short()
}
}
impl PartialEq for PublicKey {
fn eq(&self, other: &PublicKey) -> bool {
self.key == other.key
}
}
impl std::fmt::Display for PublicKey {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
iroh::PublicKey::from(self).fmt(f)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_public_key() {
let key_str =
String::from("523c7996bad77424e96786cf7a7205115337a5b4565cd25506a0f297b191a5ea");
let fmt_str = String::from("523c7996ba");
let bytes = b"\x52\x3c\x79\x96\xba\xd7\x74\x24\xe9\x67\x86\xcf\x7a\x72\x05\x11\x53\x37\xa5\xb4\x56\x5c\xd2\x55\x06\xa0\xf2\x97\xb1\x91\xa5\xea";
let key = PublicKey::from_string(key_str.clone()).unwrap();
assert_eq!(key_str, key.to_string());
assert_eq!(bytes.to_vec(), key.to_bytes());
assert_eq!(fmt_str, key.fmt_short());
let key_0 = PublicKey::from_bytes(bytes.to_vec()).unwrap();
assert_eq!(key_str, key_0.to_string());
assert_eq!(bytes.to_vec(), key_0.to_bytes());
assert_eq!(fmt_str, key_0.fmt_short());
assert!(key.equal(&key_0));
assert!(key_0.equal(&key));
}
}