1use std::{cell::RefCell, collections::HashSet};
2
3use endr::{SetItemID, SetItem};
4use litl::impl_debug_as_litl;
5use ridl::signing::{Signed, SignerID};
6use serde_derive::{Deserialize, Serialize};
7use ti64::MsSinceEpoch;
8
9use crate::CrewChange;
10
11#[derive(Clone, Serialize, Deserialize)]
12pub struct CrewChangeTx {
13 pub(crate) content: Signed<CrewChangeTxContent>,
14 pub(crate) by: SignerID,
15}
16impl_debug_as_litl!(CrewChangeTx);
17
18impl CrewChangeTx {
19 pub fn as_test_entry(&self) -> CrewChangeTxEntry {
20 CrewChangeTxEntry(SetItem::new(self.clone(), None).id(), &self)
21 }
22}
23
24#[derive(Clone, Serialize, Deserialize)]
25
26pub struct CrewChangeTxContent {
27 pub(crate) changes: Vec<CrewChange>,
28 pub(crate) made_at: MsSinceEpoch,
29}
30impl_debug_as_litl!(CrewChangeTxContent);
31
32pub struct CrewChangeTxEntry<'a>(pub SetItemID, pub &'a CrewChangeTx);
33
34impl<'a> CrewChangeTxEntry<'a> {
35 pub fn correctly_signed(&self) -> Result<(), String> {
36 CORRECTLY_SIGNED_CACHE.with(|cache| {
37 if cache.borrow().contains(&self.0) {
38 return Ok(());
39 }
40 let result = self
41 .1
42 .content
43 .ensure_signed_by(&self.1.by)
44 .map_err(|err| err.to_string());
45 if result.is_ok() {
46 cache.borrow_mut().insert(self.0.clone());
47 }
48 result
49 })
50 }
51}
52
53thread_local! {
54 static CORRECTLY_SIGNED_CACHE: RefCell<HashSet<SetItemID>> = RefCell::new(HashSet::new());
55}