forked from oppi.li/pdsfs
mount an atproto PDS repository as a FUSE filesystem

add tid

Changed files
+30 -5
src
+30 -5
src/fs.rs
··· 1 - use std::time; 1 + use std::time::{self, SystemTime, UNIX_EPOCH, Duration}; 2 2 3 3 use atrium_repo::{Repository, blockstore::AsyncBlockStoreRead}; 4 4 use futures::StreamExt; 5 5 use indexmap::{IndexMap, IndexSet}; 6 6 7 7 type Inode = usize; 8 + 9 + /// Decode a TID (timestamp identifier) to get the timestamp in microseconds since Unix epoch 10 + fn tid_to_timestamp(tid: &str) -> Option<SystemTime> { 11 + const S32_CHAR: &[u8] = b"234567abcdefghijklmnopqrstuvwxyz"; 12 + 13 + if tid.len() != 13 { 14 + return None; 15 + } 16 + 17 + let mut value: u64 = 0; 18 + for ch in tid.chars() { 19 + let pos = S32_CHAR.iter().position(|&c| c as char == ch)?; 20 + // Big-endian: first character is most significant 21 + value = (value << 5) | (pos as u64); 22 + } 23 + 24 + // Extract timestamp from upper bits (shifted by 10) 25 + let micros = value >> 10; 26 + 27 + UNIX_EPOCH.checked_add(Duration::from_micros(micros)) 28 + } 8 29 9 30 pub struct PdsFs<R> { 10 31 repos: IndexMap<String, Repository<R>>, ··· 172 193 .map_or(0, |v| serde_json::to_string(&v).unwrap().len()) 173 194 as u64; 174 195 let blocks = ((size as u32 + BLKSIZE - 1) / BLKSIZE) as u64; 196 + 197 + // Decode TID to get creation timestamp 198 + let timestamp = tid_to_timestamp(&r.rkey).unwrap_or(time::UNIX_EPOCH); 199 + 175 200 fuser::FileAttr { 176 201 ino, 177 202 size, 178 203 blocks, 179 - atime: time::UNIX_EPOCH, 180 - mtime: time::UNIX_EPOCH, 181 - ctime: time::UNIX_EPOCH, 182 - crtime: time::UNIX_EPOCH, 204 + atime: timestamp, 205 + mtime: timestamp, 206 + ctime: timestamp, 207 + crtime: timestamp, 183 208 kind: fuser::FileType::RegularFile, 184 209 perm: 0o644, 185 210 nlink: 1,