use anyhow::{Result, anyhow};
use log::{error, info};
use pyo3::prelude::*;
use std::fmt::{Debug, Display, LowerHex};
#[derive(Clone, Copy, FromPyObject, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct LongHash([u8; 32]);
impl LongHash {
pub fn new(b: &[u8]) -> Result<Self> {
if b.len() == 32 {
let mut buf = [0; 32];
buf.copy_from_slice(b);
Ok(Self(buf))
} else {
Err(anyhow!("Slice should be 32 bytes long!"))
}
}
pub fn from_hex_str(hex: &str) -> Result<Self> {
let hash = hex::decode(hex)?;
if hash.len() == 32 {
let mut bytes: [u8; 32] = [0; 32];
bytes.copy_from_slice(&hash[..32]);
Ok(Self(bytes))
} else {
Err(anyhow!(
"hex string is wrong length -- it should be 32 bytes (64 ascii chars)"
))
}
}
pub fn tiny_hash(&self) -> String {
format!("{self:x}")[..7].to_string()
}
pub fn value(&self) -> [u8; 32] {
self.0
}
}
impl Display for LongHash {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{self:x}")
}
}
impl Debug for LongHash {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{self:x}")
}
}
impl LowerHex for LongHash {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let hex = hex::encode(self.0);
write!(f, "{hex}")?;
Ok(())
}
}
#[derive(Clone, Copy, FromPyObject, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct ShortHash([u8; 16]);
impl ShortHash {
pub fn new(b: &[u8]) -> Result<Self> {
if b.len() == 16 {
let mut buf = [0; 16];
buf.copy_from_slice(b);
Ok(Self(buf))
} else {
Err(anyhow!("Slice should be 16 bytes long!"))
}
}
pub fn from_hex_str(hex: &str) -> Result<Self> {
let hash = hex::decode(hex)?;
if hash.len() == 16 {
let mut bytes: [u8; 16] = [0; 16];
bytes.copy_from_slice(&hash[..16]);
Ok(Self(bytes))
} else {
Err(anyhow!(
"hex string is wrong length -- it should be 16 bytes (32 ascii chars)"
))
}
}
pub fn tiny_hash(&self) -> String {
format!("{self:x}")[..7].to_string()
}
pub fn value(&self) -> [u8; 16] {
self.0
}
}
impl Display for ShortHash {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{self:x}")
}
}
impl Debug for ShortHash {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{self:x}")
}
}
impl LowerHex for ShortHash {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let hex = hex::encode(self.0);
write!(f, "{hex}")?;
Ok(())
}
}
#[pyclass]
pub(crate) struct StdOutLog;
#[pymethods]
impl StdOutLog {
pub(crate) fn write(&self, data: &str) {
let data = data.trim();
if !data.is_empty() {
info!("python: {data:?}");
}
}
}
#[pyclass]
pub(crate) struct StdErrLog;
#[pymethods]
impl StdErrLog {
pub(crate) fn write(&self, data: &str) {
let data = data.trim();
if !data.is_empty() {
error!("python: {data:?}");
}
}
}