hst_deactivations/
file.rs1use super::{DeactivationLog, Entry, Error};
2use chrono::{DateTime, Utc};
3use fd_lock::RwLock as FdLock;
4use std::collections::HashMap;
5use std::fs::File;
6use std::io::{Seek, Write};
7use std::ops::DerefMut;
8use std::path::Path;
9use std::sync::{Arc, Mutex, RwLock};
10
11#[derive(Clone, Debug)]
12pub struct DeactivationFile {
13 file: Arc<Mutex<FdLock<File>>>,
14 log: Arc<RwLock<DeactivationLog>>,
15}
16
17impl DeactivationFile {
18 pub fn open<P: AsRef<Path>>(path: P) -> Result<Self, Error> {
19 let file = File::options().read(true).write(true).open(&path)?;
20 let log = DeactivationLog::read(&file)?;
21
22 Ok(Self {
23 file: Arc::new(Mutex::new(FdLock::new(file))),
24 log: Arc::new(RwLock::new(log)),
25 })
26 }
27
28 pub fn log(&self) -> DeactivationLog {
29 let log = self.log.read().unwrap();
30 log.clone()
31 }
32
33 pub fn lookup(&self, user_id: u64) -> Option<Vec<Entry>> {
34 let log = self.log.read().unwrap();
35 log.lookup(user_id)
36 }
37
38 pub fn status(&self, user_id: u64) -> Option<u32> {
39 let log = self.log.read().unwrap();
40 log.status(user_id)
41 }
42
43 pub fn add(&self, user_id: u64, status: u32, observed: DateTime<Utc>) {
44 let mut log = self.log.write().unwrap();
45 log.add(user_id, status, observed);
46 }
47
48 pub fn add_all(&self, updates: HashMap<u64, (u32, DateTime<Utc>)>) {
49 let mut log = self.log.write().unwrap();
50 log.add_all(updates);
51 }
52
53 pub fn flush(&self) -> Result<(), Error> {
54 let log = self.log.read().unwrap();
55 let mut mutex = self.file.lock().unwrap();
56 let mut file = mutex.write()?;
57
58 file.set_len(0)?;
59 file.rewind()?;
60 log.write(file.deref_mut())?;
61 file.flush()?;
62
63 Ok(())
64 }
65}