use crate::common::hash::Hash256;
use crate::common::inscriptions::Genesis;
use crate::common::mime::{Extension, Other};
use crate::common::tokens::InscriptionProtocol;
use crate::external::electrs::{ElectrsDataswampBlock, ElectrsInscription, ProtocolKey};
use crate::utils::sha256::IntoHash256;
use serde::{Deserialize, Serialize};
use sha2::Digest;
use std::fmt::{Display, Formatter};
use super::electrs::BlockInfo;
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct PreviewerBlockData {
pub block_info: BlockInfo,
pub inscriptions: Vec<PreviewerInscriptionData>,
pub moved_valid_tokens: Vec<Genesis>,
}
#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct PreviewerInscriptionData {
pub genesis: Genesis,
pub content: Vec<u8>,
pub primary_key: PreviewerInscriptionKey,
pub delegate: Option<Genesis>,
}
#[derive(Deserialize, Serialize, Clone, Eq, PartialEq, Hash, Debug)]
pub struct PreviewerInscriptionKey {
pub number: u64,
pub content_hash: Hash256,
pub extension: Extension,
pub protocol: Option<InscriptionProtocol>,
}
impl PreviewerInscriptionKey {
pub fn generate_hash(&self) -> Hash256 {
let mut buffer = Vec::new();
buffer.extend(self.content_hash.0);
buffer.extend(serde_json::to_vec(&self.extension).expect("Must generate vec from extension"));
buffer.extend(
self.protocol
.as_ref()
.map(|protocol| serde_json::to_vec(protocol).expect("Must generate vec from protocol"))
.unwrap_or_default(),
);
buffer.hash_256()
}
pub fn generate_path(&self) -> String {
let hash = self.generate_hash();
let file_type = self.extension.file_type();
format!("{file_type}/{hash}")
}
}
impl Display for PreviewerInscriptionKey {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let hash = self.content_hash;
let protocol = self.protocol.clone().map(|p| format!("{p:?}")).unwrap_or_default();
let extension = self.extension.to_string();
write!(f, "{hash}-{protocol}-{extension}")
}
}
impl From<ElectrsDataswampBlock> for PreviewerBlockData {
fn from(value: ElectrsDataswampBlock) -> Self {
let inscriptions = value
.inscriptions
.iter()
.map(|x| PreviewerInscriptionData {
genesis: x.location.genesis,
content: x.clone().content.unwrap_or_default(),
delegate: None,
primary_key: PreviewerInscriptionKey::from(
x.clone(),
value
.protocol
.get(&ProtocolKey {
tx_index: x.tx_index,
inscription_number: x.number,
})
.cloned(),
),
})
.collect();
Self {
block_info: value.block_info,
inscriptions,
moved_valid_tokens: vec![],
}
}
}
impl PreviewerInscriptionKey {
fn from(value: ElectrsInscription, protocol: Option<InscriptionProtocol>) -> Self {
let mut hasher = sha2::Sha256::new();
hasher.update(value.content.as_deref().unwrap_or_default());
let content_hash = Hash256(hasher.finalize().into());
let extension = value.content_type.unwrap_or_default().parse().unwrap_or(Extension::Other(Other::Bytes));
Self {
content_hash,
extension,
protocol,
number: value.number.0,
}
}
}