Skip to main content

tnnl/
store.rs

1use std::sync::atomic::{AtomicU64, Ordering};
2
3use serde::{Deserialize, Serialize};
4
5static NEXT_ID: AtomicU64 = AtomicU64::new(1);
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct StoredRequest {
9    pub id: u64,
10    pub port: u16,
11    pub method: String,
12    pub path: String,
13    pub raw_headers: String,
14    pub body_b64: String,
15}
16
17fn store_path() -> std::path::PathBuf {
18    std::env::temp_dir().join("tnnl-requests.jsonl")
19}
20
21pub fn init() {
22    let max = read_all().into_iter().map(|r| r.id).max().unwrap_or(0);
23    NEXT_ID.store(max + 1, Ordering::Relaxed);
24}
25
26pub fn next_id() -> u64 {
27    NEXT_ID.fetch_add(1, Ordering::Relaxed)
28}
29
30pub fn store(req: StoredRequest) {
31    let Ok(mut f) = std::fs::OpenOptions::new()
32        .create(true)
33        .append(true)
34        .open(store_path())
35    else {
36        return;
37    };
38    if let Ok(line) = serde_json::to_string(&req) {
39        use std::io::Write;
40        let _ = writeln!(f, "{line}");
41    }
42}
43
44pub fn find(id: u64) -> Option<StoredRequest> {
45    read_all().into_iter().find(|r| r.id == id)
46}
47
48fn read_all() -> Vec<StoredRequest> {
49    let Ok(content) = std::fs::read_to_string(store_path()) else {
50        return vec![];
51    };
52    content
53        .lines()
54        .filter_map(|l| serde_json::from_str(l).ok())
55        .collect()
56}