computation_process/
computable_identity.rs

1use crate::{Completable, Computable};
2use serde::{Deserialize, Serialize};
3
4/// A trivial [`Computable`] that immediately returns a pre-computed value.
5///
6/// This is useful for wrapping an already-computed value in the [`Computable`] interface,
7/// allowing it to be used in contexts that expect a computation.
8///
9/// After the value is returned once, subsequent calls to [`Computable::try_compute`] will
10/// return [`Incomplete::Exhausted`](crate::Incomplete::Exhausted).
11///
12/// # Example
13///
14/// ```rust
15/// use computation_process::{ComputableIdentity, Computable};
16///
17/// let mut identity: ComputableIdentity<i32> = 42.into();
18/// assert_eq!(identity.try_compute(), Ok(42));
19/// ```
20#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
21pub struct ComputableIdentity<T> {
22    value: Option<T>,
23}
24
25impl<T> From<T> for ComputableIdentity<T> {
26    fn from(value: T) -> Self {
27        ComputableIdentity { value: Some(value) }
28    }
29}
30
31impl<T> Computable<T> for ComputableIdentity<T> {
32    fn try_compute(&mut self) -> Completable<T> {
33        if let Some(result) = self.value.take() {
34            Ok(result)
35        } else {
36            Err(crate::Incomplete::Exhausted)
37        }
38    }
39}
40
41#[cfg(test)]
42mod tests {
43    use super::*;
44    use crate::Computable;
45
46    #[test]
47    fn test_computable_identity_from() {
48        let identity: ComputableIdentity<i32> = 42.into();
49        let mut identity = identity;
50        let result = identity.try_compute().unwrap();
51        assert_eq!(result, 42);
52    }
53
54    #[test]
55    fn test_computable_identity_compute() {
56        let mut identity: ComputableIdentity<String> = "hello".to_string().into();
57        let result = identity.compute().unwrap();
58        assert_eq!(result, "hello");
59    }
60
61    #[test]
62    fn test_computable_identity_exhausted() {
63        let mut identity: ComputableIdentity<i32> = 42.into();
64        let _ = identity.try_compute().unwrap();
65        // The second call should return Exhausted
66        assert_eq!(identity.try_compute(), Err(crate::Incomplete::Exhausted));
67    }
68
69    #[test]
70    fn test_computable_identity_dyn_computable() {
71        let identity: ComputableIdentity<i32> = 100.into();
72        let mut dyn_computable = identity.dyn_computable();
73        let result = dyn_computable.try_compute().unwrap();
74        assert_eq!(result, 100);
75    }
76}