use rand::Rng;
use std::time::{SystemTime, UNIX_EPOCH};
pub fn get_timestamp() -> u64 {
let now = SystemTime::now();
let since_the_epoch = now.duration_since(UNIX_EPOCH).expect("Time went backwards");
since_the_epoch.as_secs()
}
pub fn random_hash() -> String {
let mut rng = rand::thread_rng();
let mut bytes = [0u8; 32];
rng.fill(&mut bytes);
sha256::digest(&bytes)
}
const NPUB_LEN: usize = 63;
const NOTE_LEN: usize = 63;
#[derive(Debug, Clone)]
pub struct ParsedTagsResult {
pub content: String,
pub tags: Vec<Vec<String>>,
}
pub fn parse_content_tags(
text: &str,
tags: Vec<Vec<String>>,
hashtag_alphabet: Option<&str>,
detect_note: bool,
detect_npub: bool,
) -> ParsedTagsResult {
let mut contents: Vec<String> = Vec::new();
let mut tags = tags;
let parts = text.split(' ');
for part in parts {
if let Some(hash) = hashtag_alphabet {
if part.starts_with('#') {
let is_hash = !part
.strip_prefix('#')
.unwrap()
.chars()
.any(|c| !hash.contains(c));
if is_hash {
let s = part.strip_prefix('#').unwrap().to_string();
tags.push(vec!["t".to_string(), s]);
}
contents.push(part.to_string());
continue;
}
}
if detect_note && part.to_lowercase().starts_with("@note") && part.len() == (NOTE_LEN + 1) {
let hex = crate::bech32::from_hb_to_hex(
crate::bech32::ToBech32Kind::Note,
&part.strip_prefix('@').unwrap().to_lowercase(),
);
if hex.is_ok() {
tags.push(vec!["e".to_string(), hex.unwrap()]);
let last_index = tags.len() - 1;
contents.push(format!("#[{last_index}]"));
} else {
contents.push(part.to_string());
}
continue;
}
if detect_npub && part.to_lowercase().starts_with("@npub") && part.len() == (NPUB_LEN + 1) {
let hex = crate::bech32::from_hb_to_hex(
crate::bech32::ToBech32Kind::PublicKey,
&part.strip_prefix('@').unwrap().to_lowercase(),
);
if hex.is_ok() {
tags.push(vec!["p".to_string(), hex.unwrap()]);
let last_index = tags.len() - 1;
contents.push(format!("#[{last_index}]"));
} else {
contents.push(part.to_string());
}
continue;
}
contents.push(part.to_string());
}
ParsedTagsResult {
content: contents.join(" "),
tags,
}
}