1use std::hash::{Hash, Hasher};
2use std::marker::PhantomData;
3use std::ops::Deref;
4use std::rc::Rc;
5
6use serde::{Serialize, Serializer};
7
8mod cell;
9mod prelude;
10mod prepare;
11
12pub use cell::Cell;
13pub use prelude::*;
14pub use prepare::Prepare;
15
16#[derive(Clone, PartialEq, Eq)]
17pub enum Value<T> {
18 Ref {
19 path: String,
20 value: Option<Box<Value<T>>>,
21 },
22 Value {
23 value: Rc<T>,
24 },
25}
26
27pub struct Computed<T> {
28 _p: PhantomData<T>,
29}
30
31impl<T> Value<T> {
32 pub fn get(&self) -> Rc<T> {
33 match &self {
34 Value::Ref {
35 value: Some(value), ..
36 } => value.get(),
37 Value::Value { value } => value.clone(),
38 _ => unimplemented!("can not unknown referenced values"),
39 }
40 }
41}
42
43impl<T> Deref for Value<T> {
44 type Target = T;
45
46 fn deref(&self) -> &Self::Target {
47 match self {
48 Value::Ref {
49 value: Some(value), ..
50 } => value,
51 Value::Value { value } => value,
52 _ => unimplemented!("can not dereference computed values"),
53 }
54 }
55}
56
57impl<T: Hash> Hash for Value<T> {
58 fn hash<H: Hasher>(&self, state: &mut H) {
59 match self {
60 Value::Ref { path, .. } => {
61 state.write(b"${");
62 path.hash(state);
63 state.write(b"}");
64 }
65 Value::Value { value } => value.hash(state),
66 }
67 }
68}
69
70impl<T> Default for Computed<T> {
71 fn default() -> Self {
72 Self { _p: PhantomData }
73 }
74}
75
76impl<T> Prepare for Computed<T> {
77 fn prepare(self, _: impl Into<String>) -> Self {
78 self
79 }
80}
81
82impl<T> Clone for Computed<T> {
83 fn clone(&self) -> Self {
84 Self { _p: PhantomData }
85 }
86}
87
88impl<T: Serialize> Serialize for Value<T> {
89 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
90 where
91 S: Serializer,
92 {
93 match self {
94 Value::Ref { path, .. } => format!("${{{path}}}").serialize(serializer),
95 Value::Value { value } => value.serialize(serializer),
96 }
97 }
98}
99
100impl<T: Prepare + Clone> Prepare for Value<T> {
101 fn prepare(self, prefix: impl Into<String>) -> Self {
102 match self {
103 Value::Ref { .. } => self,
104 Value::Value { value } => Self::Value {
105 value: value.prepare(prefix),
106 },
107 }
108 }
109}