1use super::data_sources::{DataSource, DataSourceStatus};
2use super::names::{InvalidName, Name};
3use super::providers::Error;
4use crate::blobs::Blob;
5use crate::notebooks::Cell;
6use crate::providers::{ConfigSchema, ProviderConfig, SupportedQueryType};
7use crate::timestamps::Timestamp;
8use base64uuid::{Base64Uuid, InvalidId};
9#[cfg(feature = "fp-bindgen")]
10use fp_bindgen::prelude::Serializable;
11use serde::{Deserialize, Serialize};
12use std::fmt::{self, Debug, Formatter};
13use std::{convert::TryFrom, str::FromStr};
14use strum_macros::Display;
15use typed_builder::TypedBuilder;
16
17#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, TypedBuilder)]
18#[non_exhaustive]
19#[serde(rename_all = "camelCase")]
20pub struct Proxy {
21 #[builder(setter(into))]
22 pub id: Base64Uuid,
23
24 pub name: Name,
25
26 pub status: ProxyStatus,
27
28 #[builder(default)]
29 pub data_sources: Vec<DataSource>,
30
31 #[builder(default, setter(into, strip_option))]
32 #[serde(default, skip_serializing_if = "Option::is_none")]
33 pub token: Option<ProxyToken>,
34
35 #[builder(default, setter(into, strip_option))]
36 #[serde(default, skip_serializing_if = "Option::is_none")]
37 pub description: Option<String>,
38
39 #[builder(setter(into))]
40 pub created_at: Timestamp,
41
42 #[builder(setter(into))]
43 pub updated_at: Timestamp,
44}
45
46#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, TypedBuilder)]
47#[cfg_attr(
48 feature = "fp-bindgen",
49 derive(Serializable),
50 fp(rust_module = "fiberplane_models::proxies")
51)]
52#[non_exhaustive]
53#[serde(rename_all = "camelCase")]
54pub struct ProxySummary {
55 #[builder(setter(into))]
56 pub id: Base64Uuid,
57
58 pub name: Name,
59
60 pub status: ProxyStatus,
61}
62
63impl From<Proxy> for ProxySummary {
64 fn from(proxy: Proxy) -> Self {
65 Self {
66 id: proxy.id,
67 name: proxy.name,
68 status: proxy.status,
69 }
70 }
71}
72
73#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone, Copy, Display)]
74#[cfg_attr(
75 feature = "fp-bindgen",
76 derive(Serializable),
77 fp(rust_module = "fiberplane_models::proxies")
78)]
79#[non_exhaustive]
80#[serde(rename_all = "snake_case")]
81pub enum ProxyStatus {
82 Connected,
83 Disconnected,
84}
85
86#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, TypedBuilder)]
87#[cfg_attr(
88 feature = "fp-bindgen",
89 derive(Serializable),
90 fp(rust_module = "fiberplane_models::proxies")
91)]
92#[non_exhaustive]
93#[serde(rename_all = "camelCase")]
94pub struct NewProxy {
95 pub name: Name,
96
97 #[builder(default, setter(into, strip_option))]
98 pub description: Option<String>,
99}
100
101#[derive(Debug, thiserror::Error, PartialEq, Eq)]
102#[cfg_attr(
103 feature = "fp-bindgen",
104 derive(Serializable),
105 fp(rust_module = "fiberplane_models::proxies")
106)]
107#[non_exhaustive]
108pub enum InvalidProxyToken {
109 #[error("Invalid workspace ID")]
110 InvalidWorkspaceId(#[from] InvalidId),
111 #[error("Invalid proxy name")]
112 InvalidProxyName(#[from] InvalidName),
113 #[error("Missing token")]
114 MissingToken,
115}
116
117#[derive(Clone, Serialize, Deserialize, PartialEq, Eq, TypedBuilder)]
120#[cfg_attr(
121 feature = "fp-bindgen",
122 derive(Serializable),
123 fp(rust_module = "fiberplane_models::proxies")
124)]
125#[non_exhaustive]
126#[serde(try_from = "&str", into = "String")]
127pub struct ProxyToken {
128 #[builder(setter(into))]
129 pub workspace_id: Base64Uuid,
130
131 pub proxy_name: Name,
132
133 #[builder(default, setter(into))]
134 pub token: String,
135}
136
137impl Debug for ProxyToken {
138 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
139 f.debug_struct("ProxyToken")
140 .field("workspace_id", &self.workspace_id)
141 .field("proxy_name", &self.proxy_name)
142 .field("token", &"[REDACTED]")
143 .finish()
144 }
145}
146
147impl From<ProxyToken> for String {
148 fn from(token: ProxyToken) -> Self {
149 format!(
150 "{}:{}:{}",
151 token.workspace_id, token.proxy_name, token.token
152 )
153 }
154}
155
156impl FromStr for ProxyToken {
157 type Err = InvalidProxyToken;
158
159 fn from_str(s: &str) -> Result<Self, Self::Err> {
160 let mut parts = s.split(':');
161
162 let workspace_id = parts.next().unwrap_or_default().parse::<Base64Uuid>()?;
163 let proxy_name = Name::new(parts.next().unwrap_or_default())?;
164 let token = parts
165 .next()
166 .ok_or(InvalidProxyToken::MissingToken)?
167 .to_string();
168
169 Ok(ProxyToken {
170 workspace_id,
171 proxy_name,
172 token,
173 })
174 }
175}
176
177impl TryFrom<&str> for ProxyToken {
178 type Error = InvalidProxyToken;
179
180 fn try_from(s: &str) -> Result<Self, Self::Error> {
181 Self::from_str(s)
182 }
183}
184
185#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, TypedBuilder)]
186#[cfg_attr(
187 feature = "fp-bindgen",
188 derive(Serializable),
189 fp(rust_module = "fiberplane_models::proxies")
190)]
191#[non_exhaustive]
192#[serde(rename_all = "camelCase")]
193pub struct CreateCellsApiRequest {
194 pub response: Blob,
195
196 #[builder(setter(into))]
197 pub query_type: String,
198}
199
200#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, TypedBuilder)]
201#[cfg_attr(
202 feature = "fp-bindgen",
203 derive(Serializable),
204 fp(rust_module = "fiberplane_models::proxies")
205)]
206#[non_exhaustive]
207#[serde(rename_all = "camelCase")]
208pub struct ExtractDataApiRequest {
209 pub response: Blob,
210
211 #[builder(setter(into))]
212 pub mime_type: String,
213
214 #[builder(default, setter(into, strip_option))]
215 #[serde(default, skip_serializing_if = "Option::is_none")]
216 pub query: Option<String>,
217}
218
219#[derive(Debug, Deserialize, Serialize, TypedBuilder)]
221#[cfg_attr(
222 feature = "fp-bindgen",
223 derive(Serializable),
224 fp(rust_module = "fiberplane_models::proxies")
225)]
226#[non_exhaustive]
227#[serde(rename_all = "camelCase")]
228pub struct ServerMessage {
229 #[builder(setter(into))]
230 pub op_id: Base64Uuid,
231
232 pub data_source_name: Name,
233
234 pub protocol_version: u8,
235
236 #[serde(flatten)]
237 pub payload: ServerMessagePayload,
238}
239
240impl ServerMessage {
241 pub fn deserialize_msgpack(
242 input: impl AsRef<[u8]>,
243 ) -> Result<ServerMessage, rmp_serde::decode::Error> {
244 rmp_serde::from_slice(input.as_ref())
245 }
246
247 pub fn serialize_msgpack(&self) -> Vec<u8> {
248 rmp_serde::to_vec(&self).expect("MessgePack serialization error")
249 }
250
251 pub fn op_id(&self) -> Option<Base64Uuid> {
252 Some(self.op_id)
253 }
254
255 fn payload_with_header(
256 payload: ServerMessagePayload,
257 data_source_name: Name,
258 protocol_version: u8,
259 op_id: Base64Uuid,
260 ) -> Self {
261 Self {
262 op_id,
263 data_source_name,
264 protocol_version,
265 payload,
266 }
267 }
268
269 pub fn new_invoke_proxy_request(
270 data: Vec<u8>,
271 data_source_name: Name,
272 protocol_version: u8,
273 op_id: Base64Uuid,
274 ) -> Self {
275 Self::payload_with_header(
276 ServerMessagePayload::Invoke(InvokeRequest { data }),
277 data_source_name,
278 protocol_version,
279 op_id,
280 )
281 }
282
283 pub fn new_create_cells_request(
284 data: Blob,
285 query_type: String,
286 data_source_name: Name,
287 protocol_version: u8,
288 op_id: Base64Uuid,
289 ) -> Self {
290 Self::payload_with_header(
291 ServerMessagePayload::CreateCells(CreateCellsRequest {
292 response: data,
293 query_type,
294 }),
295 data_source_name,
296 protocol_version,
297 op_id,
298 )
299 }
300
301 pub fn new_extract_data_request(
302 data: Blob,
303 mime_type: String,
304 query: Option<String>,
305 data_source_name: Name,
306 protocol_version: u8,
307 op_id: Base64Uuid,
308 ) -> Self {
309 Self::payload_with_header(
310 ServerMessagePayload::ExtractData(ExtractDataRequest {
311 response: data,
312 mime_type,
313 query,
314 }),
315 data_source_name,
316 protocol_version,
317 op_id,
318 )
319 }
320
321 pub fn new_get_config_schema_request(
322 data_source_name: Name,
323 protocol_version: u8,
324 op_id: Base64Uuid,
325 ) -> Self {
326 Self::payload_with_header(
327 ServerMessagePayload::GetConfigSchema(GetConfigSchemaRequest {}),
328 data_source_name,
329 protocol_version,
330 op_id,
331 )
332 }
333
334 pub fn new_get_supported_query_types_request(
335 config: ProviderConfig,
336 data_source_name: Name,
337 protocol_version: u8,
338 op_id: Base64Uuid,
339 ) -> Self {
340 Self::payload_with_header(
341 ServerMessagePayload::GetSupportedQueryTypes(GetSupportedQueryTypesRequest { config }),
342 data_source_name,
343 protocol_version,
344 op_id,
345 )
346 }
347}
348
349#[derive(Debug, Deserialize, Serialize)]
351#[cfg_attr(
352 feature = "fp-bindgen",
353 derive(Serializable),
354 fp(rust_module = "fiberplane_models::proxies")
355)]
356#[non_exhaustive]
357#[serde(tag = "type", rename_all = "camelCase")]
358pub enum ServerMessagePayload {
359 #[serde(rename = "invokeProxy")] Invoke(InvokeRequest),
362 CreateCells(CreateCellsRequest),
364 ExtractData(ExtractDataRequest),
366 GetConfigSchema(GetConfigSchemaRequest),
368 GetSupportedQueryTypes(GetSupportedQueryTypesRequest),
370}
371
372#[derive(Deserialize, Serialize, TypedBuilder)]
373#[cfg_attr(
374 feature = "fp-bindgen",
375 derive(Serializable),
376 fp(rust_module = "fiberplane_models::proxies")
377)]
378#[non_exhaustive]
379#[serde(rename_all = "camelCase")]
380pub struct InvokeRequest {
381 #[serde(with = "serde_bytes")]
382 pub data: Vec<u8>,
383}
384
385impl Debug for InvokeRequest {
386 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
387 f.debug_struct("InvokeRequest")
388 .field("data", &format!("[{} bytes]", self.data.len()))
389 .finish()
390 }
391}
392
393#[derive(Deserialize, Serialize, TypedBuilder)]
394#[cfg_attr(
395 feature = "fp-bindgen",
396 derive(Serializable),
397 fp(rust_module = "fiberplane_models::proxies")
398)]
399#[non_exhaustive]
400#[serde(rename_all = "camelCase")]
401pub struct CreateCellsRequest {
402 pub response: Blob,
403
404 #[builder(setter(into))]
405 pub query_type: String,
406}
407
408impl Debug for CreateCellsRequest {
409 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
410 f.debug_struct("CreateCellsRequest")
411 .field("query_type", &self.query_type)
412 .field("response", &format!("[{} bytes]", self.response.data.len()))
413 .finish()
414 }
415}
416
417#[derive(Deserialize, Serialize, TypedBuilder)]
418#[cfg_attr(
419 feature = "fp-bindgen",
420 derive(Serializable),
421 fp(rust_module = "fiberplane_models::proxies")
422)]
423#[non_exhaustive]
424#[serde(rename_all = "camelCase")]
425pub struct ExtractDataRequest {
426 pub response: Blob,
427
428 #[builder(setter(into))]
429 pub mime_type: String,
430
431 #[builder(default, setter(into, strip_option))]
432 #[serde(default, skip_serializing_if = "Option::is_none")]
433 pub query: Option<String>,
434}
435
436impl Debug for ExtractDataRequest {
437 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
438 f.debug_struct("ExtractDataRequest")
439 .field("mime_type", &self.mime_type)
440 .field("query", &self.query)
441 .field("response", &format!("[{} bytes]", self.response.data.len()))
442 .finish()
443 }
444}
445
446#[derive(Deserialize, Serialize)]
447#[cfg_attr(
448 feature = "fp-bindgen",
449 derive(Serializable),
450 fp(rust_module = "fiberplane_models::proxies")
451)]
452#[non_exhaustive]
453#[serde(rename_all = "camelCase")]
454pub struct GetConfigSchemaRequest {}
455
456impl Debug for GetConfigSchemaRequest {
457 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
458 f.debug_struct("ConfigSchemaRequest").finish()
459 }
460}
461
462#[derive(Deserialize, Serialize, Debug, TypedBuilder)]
463#[cfg_attr(
464 feature = "fp-bindgen",
465 derive(Serializable),
466 fp(rust_module = "fiberplane_models::proxies")
467)]
468#[non_exhaustive]
469#[serde(rename_all = "camelCase")]
470pub struct GetSupportedQueryTypesRequest {
471 pub config: ProviderConfig,
472}
473
474#[derive(Debug, Deserialize, Serialize, TypedBuilder)]
476#[cfg_attr(
477 feature = "fp-bindgen",
478 derive(Serializable),
479 fp(rust_module = "fiberplane_models::proxies")
480)]
481#[non_exhaustive]
482#[serde(rename_all = "camelCase")]
483pub struct ProxyMessage {
484 #[builder(default, setter(into, strip_option))]
485 pub op_id: Option<Base64Uuid>,
486
487 #[serde(flatten)]
488 pub payload: ProxyMessagePayload,
489}
490
491impl ProxyMessage {
492 fn response(payload: ProxyMessagePayload, op_id: Base64Uuid) -> Self {
493 Self {
494 op_id: Some(op_id),
495 payload,
496 }
497 }
498
499 fn notification(payload: ProxyMessagePayload) -> Self {
500 Self {
501 op_id: None,
502 payload,
503 }
504 }
505
506 pub fn new_error_response(error: Error, op_id: Base64Uuid) -> Self {
507 Self::response(ProxyMessagePayload::Error(ErrorMessage { error }), op_id)
508 }
509 pub fn new_invoke_proxy_response(data: Vec<u8>, op_id: Base64Uuid) -> Self {
510 Self::response(
511 ProxyMessagePayload::InvokeProxyResponse(InvokeProxyResponseMessage { data }),
512 op_id,
513 )
514 }
515 pub fn new_create_cells_response(cells: Result<Vec<Cell>, Error>, op_id: Base64Uuid) -> Self {
516 Self::response(
517 ProxyMessagePayload::CreateCellsResponse(CreateCellsResponseMessage { cells }),
518 op_id,
519 )
520 }
521 pub fn new_extract_data_response(data: Result<Blob, Error>, op_id: Base64Uuid) -> Self {
522 Self::response(
523 ProxyMessagePayload::ExtractDataResponse(ExtractDataResponseMessage { data }),
524 op_id,
525 )
526 }
527 pub fn new_config_schema_response(schema: ConfigSchema, op_id: Base64Uuid) -> Self {
528 Self::response(
529 ProxyMessagePayload::GetConfigSchemaResponse(GetConfigSchemaResponseMessage { schema }),
530 op_id,
531 )
532 }
533 pub fn new_supported_query_types_response(
534 queries: Vec<SupportedQueryType>,
535 op_id: Base64Uuid,
536 ) -> Self {
537 Self::response(
538 ProxyMessagePayload::GetSupportedQueryTypesResponse(
539 GetSupportedQueryTypesResponseMessage { queries },
540 ),
541 op_id,
542 )
543 }
544 pub fn new_set_data_sources_notification(data_sources: Vec<UpsertProxyDataSource>) -> Self {
545 Self::notification(ProxyMessagePayload::SetDataSources(SetDataSourcesMessage {
546 data_sources,
547 }))
548 }
549}
550
551#[derive(Debug, Deserialize, Serialize)]
553#[cfg_attr(
554 feature = "fp-bindgen",
555 derive(Serializable),
556 fp(rust_module = "fiberplane_models::proxies")
557)]
558#[non_exhaustive]
559#[serde(tag = "type", rename_all = "camelCase")]
560pub enum ProxyMessagePayload {
561 SetDataSources(SetDataSourcesMessage),
562 InvokeProxyResponse(InvokeProxyResponseMessage),
563 CreateCellsResponse(CreateCellsResponseMessage),
564 ExtractDataResponse(ExtractDataResponseMessage),
565 GetConfigSchemaResponse(GetConfigSchemaResponseMessage),
566 GetSupportedQueryTypesResponse(GetSupportedQueryTypesResponseMessage),
567 Error(ErrorMessage),
568}
569
570impl From<(ErrorMessage, Base64Uuid)> for ProxyMessage {
571 fn from((message, op_id): (ErrorMessage, Base64Uuid)) -> Self {
572 Self::response(ProxyMessagePayload::Error(message), op_id)
573 }
574}
575
576#[derive(Deserialize, Serialize, TypedBuilder)]
577#[cfg_attr(
578 feature = "fp-bindgen",
579 derive(Serializable),
580 fp(rust_module = "fiberplane_models::proxies")
581)]
582#[non_exhaustive]
583#[serde(rename_all = "camelCase")]
584pub struct InvokeProxyResponseMessage {
585 #[serde(with = "serde_bytes")]
586 pub data: Vec<u8>,
587}
588
589impl Debug for InvokeProxyResponseMessage {
590 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
591 f.debug_struct("InvokeProxyResponseMessage")
592 .field("data", &format!("[{} bytes]", self.data.len()))
593 .finish()
594 }
595}
596
597#[derive(Deserialize, Serialize, Debug, TypedBuilder)]
598#[cfg_attr(
599 feature = "fp-bindgen",
600 derive(Serializable),
601 fp(rust_module = "fiberplane_models::proxies")
602)]
603#[non_exhaustive]
604#[serde(rename_all = "camelCase")]
605pub struct ExtractDataResponseMessage {
606 pub data: Result<Blob, Error>,
607}
608
609#[derive(Deserialize, Serialize, Debug, TypedBuilder)]
610#[cfg_attr(
611 feature = "fp-bindgen",
612 derive(Serializable),
613 fp(rust_module = "fiberplane_models::proxies")
614)]
615#[non_exhaustive]
616#[serde(rename_all = "camelCase")]
617pub struct CreateCellsResponseMessage {
618 pub cells: Result<Vec<Cell>, Error>,
619}
620
621#[derive(Deserialize, Serialize, Debug, TypedBuilder)]
622#[cfg_attr(
623 feature = "fp-bindgen",
624 derive(Serializable),
625 fp(rust_module = "fiberplane_models::proxies")
626)]
627#[non_exhaustive]
628#[serde(rename_all = "camelCase")]
629pub struct GetConfigSchemaResponseMessage {
630 pub schema: ConfigSchema,
631}
632
633#[derive(Deserialize, Serialize, Debug, TypedBuilder)]
634#[cfg_attr(
635 feature = "fp-bindgen",
636 derive(Serializable),
637 fp(rust_module = "fiberplane_models::proxies")
638)]
639#[non_exhaustive]
640#[serde(rename_all = "camelCase")]
641pub struct GetSupportedQueryTypesResponseMessage {
642 pub queries: Vec<SupportedQueryType>,
643}
644
645#[derive(Debug, Deserialize, Serialize, TypedBuilder)]
646#[cfg_attr(
647 feature = "fp-bindgen",
648 derive(Serializable),
649 fp(rust_module = "fiberplane_models::proxies")
650)]
651#[non_exhaustive]
652#[serde(rename_all = "camelCase")]
653pub struct ErrorMessage {
654 pub error: Error,
655}
656
657impl ProxyMessage {
658 pub fn deserialize_msgpack(
659 input: impl AsRef<[u8]>,
660 ) -> Result<ProxyMessage, rmp_serde::decode::Error> {
661 rmp_serde::from_slice(input.as_ref())
662 }
663
664 pub fn serialize_msgpack(&self) -> Vec<u8> {
665 rmp_serde::to_vec_named(&self).expect("MessgePack serialization error")
666 }
667
668 pub fn op_id(&self) -> Option<Base64Uuid> {
669 self.op_id
670 }
671}
672
673#[derive(Debug, Deserialize, Serialize, TypedBuilder)]
674#[cfg_attr(
675 feature = "fp-bindgen",
676 derive(Serializable),
677 fp(rust_module = "fiberplane_models::proxies")
678)]
679#[non_exhaustive]
680#[serde(rename_all = "camelCase")]
681pub struct SetDataSourcesMessage {
682 pub data_sources: Vec<UpsertProxyDataSource>,
683}
684
685#[derive(Debug, Deserialize, Serialize, PartialEq, Eq, Clone, TypedBuilder)]
686#[cfg_attr(
687 feature = "fp-bindgen",
688 derive(Serializable),
689 fp(rust_module = "fiberplane_models::proxies")
690)]
691#[non_exhaustive]
692#[serde(tag = "type", rename_all = "camelCase")]
693pub struct UpsertProxyDataSource {
694 pub name: Name,
695
696 #[builder(default, setter(into, strip_option))]
697 pub description: Option<String>,
698
699 #[builder(setter(into))]
700 pub provider_type: String,
701
702 #[builder(default)]
703 #[serde(default)]
704 pub protocol_version: u8,
705
706 #[serde(flatten)]
707 pub status: DataSourceStatus,
708}
709
710#[cfg(test)]
711mod tests {
712 use super::*;
713 use crate::providers::Error;
714
715 #[test]
716 fn serialization_deserialization() {
717 let data_sources = vec![
718 UpsertProxyDataSource {
719 name: Name::from_static("prometheus-prod"),
720 provider_type: "prometheus".to_string(),
721 protocol_version: 2,
722 description: Some("Production Prometheus".to_string()),
723 status: DataSourceStatus::Connected,
724 },
725 UpsertProxyDataSource {
726 name: Name::from_static("elasticsearch-prod"),
727 provider_type: "elasticsearch".to_string(),
728 protocol_version: 1,
729 description: None,
730 status: DataSourceStatus::Error(Error::NotFound),
731 },
732 ];
733 let message = ProxyMessage::new_set_data_sources_notification(data_sources.clone());
734 let serialized = message.serialize_msgpack();
735 let deserialized = ProxyMessage::deserialize_msgpack(serialized).unwrap();
736 if let ProxyMessage {
737 op_id: None,
738 payload: ProxyMessagePayload::SetDataSources(set_data_sources),
739 } = deserialized
740 {
741 assert_eq!(set_data_sources.data_sources, data_sources)
742 } else {
743 panic!("Unexpected message type");
744 }
745 }
746
747 #[test]
748 fn backwards_compatibility() {
749 mod old {
751 use crate::names::Name;
752 use base64uuid::Base64Uuid;
753 use serde::{Deserialize, Serialize};
754
755 #[derive(Debug, Deserialize, Serialize)]
756 #[serde(tag = "type", rename_all = "camelCase")]
757 pub enum ServerMessage {
758 InvokeProxy(InvokeProxyMessage),
759 }
760
761 #[derive(Debug, Deserialize, Serialize, Clone)]
762 #[serde(rename_all = "camelCase")]
763 pub struct InvokeProxyMessage {
764 pub op_id: Base64Uuid,
765 pub data_source_name: Name,
766 #[serde(with = "serde_bytes")]
767 pub data: Vec<u8>,
768 pub protocol_version: u8,
769 }
770 }
771
772 let op_id = Base64Uuid::parse_str("34edc58d-f8ec-4c95-bce0-c2ae8800e6ef").unwrap();
773 let data_source_name = Name::from_static("test-name");
774 let data = b"aieu".to_vec();
775 let old_message = old::InvokeProxyMessage {
776 op_id,
777 data_source_name,
778 protocol_version: 12,
779 data,
780 };
781
782 let new_message: ServerMessage = rmp_serde::from_slice(
783 &rmp_serde::to_vec_named(&old::ServerMessage::InvokeProxy(old_message.clone()))
784 .unwrap(),
785 )
786 .unwrap();
787
788 assert_eq!(new_message.op_id, old_message.op_id);
789 assert_eq!(new_message.data_source_name, old_message.data_source_name);
790 assert_eq!(new_message.protocol_version, old_message.protocol_version);
791
792 if let ServerMessagePayload::Invoke(response) = new_message.payload {
793 assert_eq!(response.data, old_message.data)
794 } else {
795 panic!("Wrong variant of ServerMessage deserialized. Expecting Invoke")
796 }
797 }
798}