tf_bindgen/value/
mod.rs

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}