inc_complete/storage/
singleton.rs

1use serde::{Deserialize, ser::SerializeStruct};
2
3use super::{OutputType, StorageFor};
4use crate::Cell;
5
6/// Helper to store a simple computation type which has no fields and thus
7/// does not require a map to cache each possible value.
8///
9/// Examples include `struct SourceFile;` or `struct Time;`
10pub struct SingletonStorage<K: OutputType> {
11    cell: std::sync::OnceLock<Cell>,
12    key: std::sync::OnceLock<K>,
13    value: std::sync::Mutex<Option<K::Output>>,
14}
15
16impl<K: OutputType> Default for SingletonStorage<K> {
17    fn default() -> Self {
18        Self {
19            cell: Default::default(),
20            value: Default::default(),
21            key: Default::default(),
22        }
23    }
24}
25
26impl<K> StorageFor<K> for SingletonStorage<K>
27where
28    K: OutputType + Clone,
29    K::Output: Eq + Clone,
30{
31    fn get_cell_for_computation(&self, _: &K) -> Option<Cell> {
32        self.cell.get().copied()
33    }
34
35    fn insert_new_cell(&self, cell: Cell, key: K) {
36        assert!(
37            self.cell.set(cell).is_ok(),
38            "Overwriting previous singleton value - are you using SingleStorage<{}> with a non-singleton type?",
39            std::any::type_name::<K>()
40        );
41        self.key
42            .set(key)
43            .unwrap_or_else(|_| panic!("insert_new_cell: cell already initialized"));
44    }
45
46    fn get_input(&self, _: Cell) -> K {
47        self.key.get().unwrap().clone()
48    }
49
50    fn get_output(&self, _: Cell) -> Option<K::Output> {
51        self.value.lock().unwrap().clone()
52    }
53
54    fn update_output(&self, _: Cell, new_value: K::Output) -> bool {
55        let mut guard = self.value.lock().unwrap();
56        let changed = K::ASSUME_CHANGED || guard.as_ref().is_none_or(|value| *value != new_value);
57        *guard = Some(new_value);
58        changed
59    }
60}
61
62impl<K> serde::Serialize for SingletonStorage<K>
63where
64    K: serde::Serialize + OutputType,
65    K::Output: serde::Serialize,
66{
67    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
68    where
69        S: serde::Serializer,
70    {
71        let mut s = serializer.serialize_struct("SingletonStorage", 3)?;
72        if let Some(cell) = self.cell.get() {
73            s.serialize_field("cell", cell)?;
74        }
75        if let Some(key) = self.key.get() {
76            s.serialize_field("key", key)?;
77        }
78        if let Ok(lock) = self.value.lock() {
79            if let Some(value) = &*lock {
80                s.serialize_field("value", value)?;
81            }
82        }
83        s.end()
84    }
85}
86
87impl<'de, K> serde::Deserialize<'de> for SingletonStorage<K>
88where
89    K: serde::Deserialize<'de> + OutputType,
90    K::Output: serde::Deserialize<'de>,
91{
92    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
93    where
94        D: serde::Deserializer<'de>,
95    {
96        let wrapper: SerializeWrapper<K> = Deserialize::deserialize(deserializer)?;
97        Ok(wrapper.into_storage())
98    }
99}
100
101#[derive(Deserialize)]
102struct SerializeWrapper<K: OutputType> {
103    #[serde(default)]
104    cell: Option<Cell>,
105
106    // Serde complains we need a `K: Default` without this, but that shouldn't be necessary.
107    #[serde(default = "none")]
108    key: Option<K>,
109
110    #[serde(default)]
111    #[serde(bound = "K::Output: Deserialize<'de>")]
112    value: Option<K::Output>,
113}
114
115fn none<T>() -> Option<T> {
116    None
117}
118
119impl<K: OutputType> SerializeWrapper<K> {
120    fn into_storage(self) -> SingletonStorage<K> {
121        let cell = match self.cell {
122            Some(cell) => std::sync::OnceLock::from(cell),
123            None => std::sync::OnceLock::new(),
124        };
125        let key = match self.key {
126            Some(key) => std::sync::OnceLock::from(key),
127            None => std::sync::OnceLock::new(),
128        };
129        let value = std::sync::Mutex::new(self.value);
130        SingletonStorage { cell, key, value }
131    }
132}