photonic_interface_grpc_client/
input.rs

1use std::convert::Infallible;
2use std::fmt;
3use std::marker::PhantomData;
4use std::str::FromStr;
5use std::sync::Arc;
6
7use anyhow::Result;
8use parking_lot::Mutex;
9use tonic::transport::Channel;
10
11use photonic_interface_grpc_proto::interface_client::InterfaceClient;
12use photonic_interface_grpc_proto::{input_value, InputInfoResponse, InputSendRequest, InputValue, InputValueType};
13
14use crate::values::{ColorValue, RangeValue, ValueType};
15
16#[derive(Eq, PartialEq, Clone, Hash)]
17pub struct InputId(pub(crate) String);
18
19impl fmt::Display for InputId {
20    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21        f.write_str(&self.0)
22    }
23}
24
25impl fmt::Debug for InputId {
26    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27        f.write_str(&self.0)
28    }
29}
30
31impl AsRef<str> for InputId {
32    fn as_ref(&self) -> &str {
33        return &self.0;
34    }
35}
36
37impl FromStr for InputId {
38    type Err = Infallible;
39
40    fn from_str(s: &str) -> Result<Self, Self::Err> {
41        return Ok(Self(s.to_owned()));
42    }
43}
44
45pub struct Input {
46    client: Arc<Mutex<InterfaceClient<Channel>>>,
47
48    name: InputId,
49
50    value_type: ValueType,
51}
52
53impl Input {
54    pub(crate) fn from_input_info(client: Arc<Mutex<InterfaceClient<Channel>>>, info: InputInfoResponse) -> Self {
55        let value_type = match info.value_type() {
56            InputValueType::Trigger => ValueType::Trigger,
57            InputValueType::Bool => ValueType::Bool,
58            InputValueType::Integer => ValueType::Integer,
59            InputValueType::Decimal => ValueType::Decimal,
60            InputValueType::Color => ValueType::Color,
61            InputValueType::IntegerRange => ValueType::IntegerRange,
62            InputValueType::DecimalRange => ValueType::DecimalRange,
63            InputValueType::ColorRange => ValueType::ColorRange,
64        };
65
66        Self {
67            client,
68            name: InputId(info.name),
69            value_type,
70        }
71    }
72
73    pub fn name(&self) -> &InputId {
74        return &self.name;
75    }
76
77    pub fn value_type(&self) -> ValueType {
78        return self.value_type;
79    }
80
81    pub fn sink(&self) -> InputSink<'_> {
82        return match self.value_type {
83            ValueType::Trigger => InputSink::Trigger(Sink {
84                input: self,
85                value_type: PhantomData,
86            }),
87            ValueType::Bool => InputSink::Boolean(Sink {
88                input: self,
89                value_type: PhantomData,
90            }),
91            ValueType::Integer => InputSink::Integer(Sink {
92                input: self,
93                value_type: PhantomData,
94            }),
95            ValueType::Decimal => InputSink::Decimal(Sink {
96                input: self,
97                value_type: PhantomData,
98            }),
99            ValueType::Color => InputSink::Color(Sink {
100                input: self,
101                value_type: PhantomData,
102            }),
103            ValueType::IntegerRange => InputSink::IntegerRange(Sink {
104                input: self,
105                value_type: PhantomData,
106            }),
107            ValueType::DecimalRange => InputSink::DecimalRange(Sink {
108                input: self,
109                value_type: PhantomData,
110            }),
111            ValueType::ColorRange => InputSink::ColorRange(Sink {
112                input: self,
113                value_type: PhantomData,
114            }),
115        };
116    }
117}
118
119pub enum InputSink<'i> {
120    Trigger(Sink<'i, ()>),
121    Boolean(Sink<'i, bool>),
122    Integer(Sink<'i, i64>),
123    Decimal(Sink<'i, f32>),
124    Color(Sink<'i, ColorValue>),
125    IntegerRange(Sink<'i, RangeValue<i64>>),
126    DecimalRange(Sink<'i, RangeValue<f32>>),
127    ColorRange(Sink<'i, RangeValue<ColorValue>>),
128}
129
130pub struct Sink<'i, V> {
131    input: &'i Input,
132    value_type: PhantomData<V>,
133}
134
135impl Sink<'_, ()> {
136    pub async fn trigger(&self) -> Result<()> {
137        let mut client = self.input.client.lock_arc();
138
139        client
140            .input_send(InputSendRequest {
141                name: self.input.name.0.clone(),
142                value: Some(InputValue {
143                    value: Some(input_value::Value::Trigger(())),
144                }),
145            })
146            .await?;
147        return Ok(());
148    }
149}
150
151impl Sink<'_, bool> {
152    pub async fn send(&self, value: bool) -> Result<()> {
153        let mut client = self.input.client.lock_arc();
154
155        client
156            .input_send(InputSendRequest {
157                name: self.input.name.0.clone(),
158                value: Some(InputValue {
159                    value: Some(input_value::Value::Bool(value)),
160                }),
161            })
162            .await?;
163        return Ok(());
164    }
165}
166
167impl Sink<'_, i64> {
168    pub async fn send(&self, value: i64) -> Result<()> {
169        let mut client = self.input.client.lock_arc();
170
171        client
172            .input_send(InputSendRequest {
173                name: self.input.name.0.clone(),
174                value: Some(InputValue {
175                    value: Some(input_value::Value::Integer(value)),
176                }),
177            })
178            .await?;
179        return Ok(());
180    }
181}
182
183impl Sink<'_, f32> {
184    pub async fn send(&self, value: f32) -> Result<()> {
185        let mut client = self.input.client.lock_arc();
186
187        client
188            .input_send(InputSendRequest {
189                name: self.input.name.0.clone(),
190                value: Some(InputValue {
191                    value: Some(input_value::Value::Decimal(value)),
192                }),
193            })
194            .await?;
195        return Ok(());
196    }
197}
198
199impl Sink<'_, ColorValue> {
200    pub async fn send(&self, value: ColorValue) -> Result<()> {
201        let mut client = self.input.client.lock_arc();
202
203        client
204            .input_send(InputSendRequest {
205                name: self.input.name.0.clone(),
206                value: Some(InputValue {
207                    value: Some(input_value::Value::Color(value.into())),
208                }),
209            })
210            .await?;
211        return Ok(());
212    }
213}
214
215impl Sink<'_, RangeValue<i64>> {
216    pub async fn send(&self, value: RangeValue<i64>) -> Result<()> {
217        let mut client = self.input.client.lock_arc();
218
219        client
220            .input_send(InputSendRequest {
221                name: self.input.name.0.clone(),
222                value: Some(InputValue {
223                    value: Some(input_value::Value::IntegerRange(value.into())),
224                }),
225            })
226            .await?;
227        return Ok(());
228    }
229}
230
231impl Sink<'_, RangeValue<f32>> {
232    pub async fn send(&self, value: RangeValue<f32>) -> Result<()> {
233        let mut client = self.input.client.lock_arc();
234
235        client
236            .input_send(InputSendRequest {
237                name: self.input.name.0.clone(),
238                value: Some(InputValue {
239                    value: Some(input_value::Value::DecimalRange(value.into())),
240                }),
241            })
242            .await?;
243        return Ok(());
244    }
245}
246
247impl Sink<'_, RangeValue<ColorValue>> {
248    pub async fn send(&self, value: RangeValue<ColorValue>) -> Result<()> {
249        let mut client = self.input.client.lock_arc();
250
251        client
252            .input_send(InputSendRequest {
253                name: self.input.name.0.clone(),
254                value: Some(InputValue {
255                    value: Some(input_value::Value::ColorRange(value.into())),
256                }),
257            })
258            .await?;
259        return Ok(());
260    }
261}