1use luct_store::StringStoreValue;
2use serde::{Deserialize, Serialize, de::DeserializeOwned};
3use std::ops::Deref;
4use web_time::{Duration, SystemTime};
5
6#[derive(Debug, Clone, Eq, PartialOrd, Ord, Serialize, Deserialize)]
11pub struct Validated<T> {
12 inner: T,
13 validated_at: SystemTime,
14}
15
16impl<T: PartialEq> PartialEq for Validated<T> {
17 fn eq(&self, other: &Self) -> bool {
18 self.inner == other.inner
20 }
21}
22
23impl<T> Validated<T> {
24 pub(crate) fn new(inner: T) -> Self {
25 Self {
26 inner,
27 validated_at: SystemTime::now(),
28 }
29 }
30
31 pub(crate) fn validated_at(&self) -> SystemTime {
32 self.validated_at
33 }
34}
35
36impl<T> Deref for Validated<T> {
37 type Target = T;
38
39 fn deref(&self) -> &Self::Target {
40 &self.inner
41 }
42}
43
44impl<T: StringStoreValue + Serialize + DeserializeOwned> StringStoreValue for Validated<T> {
45 fn serialize_value(&self) -> String {
46 serde_json::to_string(self).unwrap()
47 }
48
49 fn deserialize_value(value: &str) -> Option<Self> {
50 serde_json::from_str(value)
51 .ok()
52 .or_else(|| Self::deserialize_value_legacy(value))
53 }
54}
55
56impl<T: StringStoreValue> Validated<T> {
57 fn deserialize_value_legacy(value: &str) -> Option<Self> {
59 let (validated_at, inner): (u64, String) = serde_json::from_str(value).ok()?;
60
61 let validated_at =
62 SystemTime::UNIX_EPOCH.checked_add(Duration::from_millis(validated_at))?;
63 let inner = T::deserialize_value(&inner)?;
64
65 Some(Self {
66 inner,
67 validated_at,
68 })
69 }
70}
71
72