rsiot/components_config/redis_client/mod.rs
1//! Конфигурация Redis-клиента
2//!
3//! Тестирование:
4//!
5//! ```bash
6//! cargo test -p rsiot-components-config --doc redis_client
7//! ```
8
9use url::Url;
10
11use crate::message::*;
12
13pub type FnInput<TMsg, TMessageChannel> =
14 fn(&Message<TMsg>) -> anyhow::Result<Option<Vec<ConfigFnInputItem<TMessageChannel>>>>;
15pub type FnOutput<TMsg> = fn(&str) -> anyhow::Result<Option<Vec<Message<TMsg>>>>;
16
17/// Конфигурация cmp_redis_client
18#[derive(Clone, Debug)]
19pub struct Config<TMsg, TMessageChannel>
20where
21 TMessageChannel: IMessageChannel,
22{
23 /// Адрес сервера Redis
24 ///
25 /// # Примеры
26 ///
27 /// ```rust
28 /// # use rsiot_components_config::redis_client::Config;
29 /// # use rsiot_components_config::redis_client as cmp_redis_client;
30 /// # // insert from tests::stub
31 /// # use rsiot_messages_core::{example_message::*, *};
32 /// # use url::Url;
33 /// # Config::<Custom, ExampleMessageChannel> {
34 /// url: Url::parse("redis://redis:6379").unwrap(),
35 /// # subscription_channel: ExampleMessageChannel::Output,
36 /// # fn_input: |_| Ok(None),
37 /// # fn_output: |_| Ok(None),
38 /// # };
39 /// ```
40 pub url: Url,
41
42 /// Название канала для подписки Pub/Sub и хеша, где хранятся сообщения
43 ///
44 /// # Примеры
45 ///
46 /// ```rust
47 /// # use rsiot_components_config::redis_client::Config;
48 /// # use rsiot_components_config::redis_client as cmp_redis_client;
49 /// # // insert from tests::stub
50 /// # use rsiot_messages_core::{example_message::*, *};
51 /// # use url::Url;
52 /// # Config::<Custom, ExampleMessageChannel> {
53 /// # url: Url::parse("redis://redis:6379").unwrap(),
54 /// subscription_channel: ExampleMessageChannel::Output,
55 /// # fn_input: |_| Ok(None),
56 /// # fn_output: |_| Ok(None),
57 /// # };
58 /// ```
59 pub subscription_channel: TMessageChannel,
60
61 /// Функция преобразования входящего потока сообщений в данные для отправки в Redis
62 ///
63 /// # Примеры
64 ///
65 /// ## Заглушка
66 ///
67 /// ```rust
68 /// # use rsiot_components_config::redis_client::Config;
69 /// # use rsiot_components_config::redis_client as cmp_redis_client;
70 /// # // insert from tests::stub
71 /// # use rsiot_messages_core::{example_message::*, *};
72 /// # use url::Url;
73 /// # Config::<Custom, ExampleMessageChannel> {
74 /// # url: Url::parse("redis://redis:6379").unwrap(),
75 /// # subscription_channel: ExampleMessageChannel::Output,
76 /// fn_input: |_| Ok(None),
77 /// # fn_output: |_| Ok(None),
78 /// # };
79 /// ```
80 ///
81 /// ## Сериализация в json
82 ///
83 /// ```rust
84 /// # use rsiot_components_config::redis_client::Config;
85 /// # use rsiot_components_config::redis_client as cmp_redis_client;
86 /// # // insert from tests::fn_input_json
87 /// # use rsiot_messages_core::{example_message::*, *};
88 /// # use url::Url;
89 /// # Config::<Custom, ExampleMessageChannel> {
90 /// # url: Url::parse("redis://redis:6379").unwrap(),
91 /// # subscription_channel: ExampleMessageChannel::Output,
92 /// fn_input: |msg: &Message<Custom>| {
93 /// let channel = ExampleMessageChannel::Output;
94 /// let key = msg.key.clone();
95 /// let value = msg.serialize()?;
96 /// Ok(Some(vec![cmp_redis_client::ConfigFnInputItem {
97 /// channel,
98 /// key,
99 /// value,
100 /// }]))
101 /// },
102 /// # fn_output: |_| Ok(None),
103 /// # };
104 /// ```
105 ///
106 /// Возможность рассылки в несколько каналов нужна для организации роутинга сообщений
107 pub fn_input: FnInput<TMsg, TMessageChannel>,
108
109 /// Функция преобразования данных из Redis в исходящий поток сообщений
110 ///
111 /// # Примеры
112 ///
113 /// ## Заглушка
114 ///
115 /// ```rust
116 /// # use rsiot_components_config::redis_client::Config;
117 /// # use rsiot_components_config::redis_client as cmp_redis_client;
118 /// # // insert from tests::stub
119 /// # use rsiot_messages_core::{example_message::*, *};
120 /// # use url::Url;
121 /// # Config::<Custom, ExampleMessageChannel> {
122 /// # url: Url::parse("redis://redis:6379").unwrap(),
123 /// # subscription_channel: ExampleMessageChannel::Output,
124 /// # fn_input: |_| Ok(None),
125 /// fn_output: |_| Ok(None),
126 /// # };
127 /// ```
128 ///
129 /// ## Десериализация из json
130 ///
131 /// ```rust
132 /// # use rsiot_components_config::redis_client::Config;
133 /// # use rsiot_components_config::redis_client as cmp_redis_client;
134 /// # // insert from tests::fn_output_json
135 /// # use rsiot_messages_core::{example_message::*, *};
136 /// # use url::Url;
137 /// # Config::<Custom, ExampleMessageChannel> {
138 /// # url: Url::parse("redis://redis:6379").unwrap(),
139 /// # subscription_channel: ExampleMessageChannel::Output,
140 /// # fn_input: |_| Ok(None),
141 /// fn_output: |text: &str| {
142 /// let msg = Message::deserialize(text)?;
143 /// Ok(Some(vec![msg]))
144 /// },
145 /// # };
146 /// ```
147 pub fn_output: FnOutput<TMsg>,
148}
149
150/// Структура с информацией для отправки данных в Redis
151pub struct ConfigFnInputItem<TMessageChannel>
152where
153 TMessageChannel: IMessageChannel,
154{
155 /// Канал Pub/Sub, в котором опубликовать сообщение
156 pub channel: TMessageChannel,
157 /// Ключ для сохранения в кеше Redis
158 pub key: String,
159 /// Значение для сохранения - само сообщение
160 pub value: String,
161}
162
163#[cfg(test)]
164mod tests {
165 // use super::*;
166 use super::super::redis_client as cmp_redis_client;
167 use super::Config;
168
169 #[test]
170 pub fn stub() {
171 use crate::message::{example_message::*, *};
172 use url::Url;
173 let _ = Config::<Custom, ExampleMessageChannel> {
174 url: Url::parse("redis://redis:6379").unwrap(),
175 subscription_channel: ExampleMessageChannel::Output,
176 fn_input: |_| Ok(None),
177 fn_output: |_| Ok(None),
178 };
179 }
180
181 #[test]
182 pub fn fn_input_json() {
183 use crate::message::{example_message::*, *};
184 use url::Url;
185 let _ = Config::<Custom, ExampleMessageChannel> {
186 url: Url::parse("redis://redis:6379").unwrap(),
187 subscription_channel: ExampleMessageChannel::Output,
188 fn_input: |msg: &Message<Custom>| {
189 let channel = ExampleMessageChannel::Output;
190 let key = msg.key.clone();
191 let value = msg.serialize()?;
192 Ok(Some(vec![cmp_redis_client::ConfigFnInputItem {
193 channel,
194 key,
195 value,
196 }]))
197 },
198 fn_output: |_| Ok(None),
199 };
200 }
201
202 #[test]
203 pub fn fn_output_json() {
204 use crate::message::{example_message::*, *};
205 use url::Url;
206 let _ = Config::<Custom, ExampleMessageChannel> {
207 url: Url::parse("redis://redis:6379").unwrap(),
208 subscription_channel: ExampleMessageChannel::Output,
209 fn_input: |_| Ok(None),
210 fn_output: |text: &str| {
211 let msg = Message::deserialize(text)?;
212 Ok(Some(vec![msg]))
213 },
214 };
215 }
216}