add: icon resolver

add: config "no_track" file list option
add: rainbeam-shared -> tetratto-shared
add: l10n
This commit is contained in:
trisua 2025-03-23 12:31:48 -04:00
parent b6fe2fba37
commit d2ca9e23d3
40 changed files with 1107 additions and 583 deletions

16
crates/shared/Cargo.toml Normal file
View file

@ -0,0 +1,16 @@
[package]
name = "tetratto-shared"
version = "0.1.0"
edition = "2024"
authors.workspace = true
repository.workspace = true
license.workspace = true
[dependencies]
chrono = "0.4.40"
hex_fmt = "0.3.0"
num-bigint = "0.4.6"
rand = "0.9.0"
serde = "1.0.219"
sha2 = "0.10.8"
uuid = { version = "1.16.0", features = ["v4"] }

38
crates/shared/src/hash.rs Normal file
View file

@ -0,0 +1,38 @@
use hex_fmt::HexFmt;
use rand::{Rng, distr::Alphanumeric, rng};
use sha2::{Digest, Sha256};
use uuid::Uuid;
// ids
pub fn uuid() -> String {
let uuid = Uuid::new_v4();
uuid.to_string()
}
pub fn hash(input: String) -> String {
let mut hasher = <Sha256 as Digest>::new();
hasher.update(input.into_bytes());
let res = hasher.finalize();
HexFmt(res).to_string()
}
pub fn hash_salted(input: String, salt: String) -> String {
let mut hasher = <Sha256 as Digest>::new();
hasher.update(format!("{salt}{input}").into_bytes());
let res = hasher.finalize();
HexFmt(res).to_string()
}
pub fn salt() -> String {
rng()
.sample_iter(&Alphanumeric)
.take(16)
.map(char::from)
.collect()
}
pub fn random_id() -> String {
hash(uuid())
}

5
crates/shared/src/lib.rs Normal file
View file

@ -0,0 +1,5 @@
pub mod hash;
pub mod snow;
pub mod time;
pub use time::{epoch_timestamp, unix_epoch_timestamp};

52
crates/shared/src/snow.rs Normal file
View file

@ -0,0 +1,52 @@
//! Almost Snowflake
//!
//! Random IDs which include timestamp information (like Twitter Snowflakes)
//!
//! IDs are generated with 41 bits of an epoch timestamp, 10 bits of a machine/server ID, and 12 bits of randomly generated numbers.
//!
//! ```
//! tttttttttttttttttttttttttttttttttttttttttiiiiiiiiiirrrrrrrrrrrr...
//! Timestamp ID Seed
//! ```
use crate::epoch_timestamp;
use serde::{Deserialize, Serialize};
use num_bigint::BigInt;
use rand::Rng;
static SEED_LEN: usize = 12;
// static ID_LEN: usize = 10;
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct AlmostSnowflake(String);
pub fn bigint(input: usize) -> BigInt {
BigInt::from(input)
}
impl AlmostSnowflake {
/// Create a new [`AlmostSnowflake`]
pub fn new(server_id: usize) -> Self {
// generate random bytes
let mut bytes = String::new();
let mut rng = rand::rng();
for _ in 1..=SEED_LEN {
bytes.push_str(&rng.random_range(0..10).to_string())
}
// build id
let mut id = bigint(epoch_timestamp(2024) as usize) << 22_u128;
id |= bigint((server_id % 1024) << 12);
id |= bigint((bytes.parse::<usize>().unwrap() + 1) % 4096);
// return
Self(id.to_string())
}
}
impl std::fmt::Display for AlmostSnowflake {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}

23
crates/shared/src/time.rs Normal file
View file

@ -0,0 +1,23 @@
use chrono::{TimeZone, Utc};
use std::time::{SystemTime, UNIX_EPOCH};
/// Get a [`u128`] timestamp
pub fn unix_epoch_timestamp() -> u128 {
let right_now = SystemTime::now();
let time_since = right_now
.duration_since(UNIX_EPOCH)
.expect("Time travel is not allowed");
time_since.as_millis()
}
/// Get a [`i64`] timestamp from the given `year` epoch
pub fn epoch_timestamp(year: i32) -> i64 {
let now = Utc::now().timestamp_millis();
let then = Utc
.with_ymd_and_hms(year, 1, 1, 0, 0, 0)
.unwrap()
.timestamp_millis();
now - then
}