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