fluvio_dataplane_protocol/
versions.rs1use std::io::{Error as IoError, ErrorKind};
2use fluvio_protocol::{Encoder, Version, Decoder};
3use fluvio_protocol::bytes::{BufMut, Buf};
4
5use crate::ErrorCode;
6use crate::api::Request;
7
8pub const VERSIONS_API_KEY: u16 = 18;
9
10#[derive(Decoder, Encoder, Default, Debug)]
15pub struct ApiVersionsRequest {
16 #[fluvio(min_version = 1)]
17 pub client_version: String,
18 #[fluvio(min_version = 1)]
19 pub client_os: String,
20 #[fluvio(min_version = 1)]
21 pub client_arch: String,
22}
23
24impl Request for ApiVersionsRequest {
25 const API_KEY: u16 = VERSIONS_API_KEY;
26 const DEFAULT_API_VERSION: i16 = 1;
27 type Response = ApiVersionsResponse;
28}
29
30pub type ApiVersions = Vec<ApiVersionKey>;
35
36#[derive(Decoder, Encoder, Default, Debug, PartialEq)]
37pub struct ApiVersionsResponse {
38 pub error_code: ErrorCode,
39 pub api_keys: ApiVersions,
40 pub platform_version: PlatformVersion,
41}
42
43#[derive(Decoder, Encoder, Default, Clone, Debug, PartialEq)]
44pub struct ApiVersionKey {
45 pub api_key: i16,
46 pub min_version: i16,
47 pub max_version: i16,
48}
49
50#[derive(Debug, PartialEq)]
51pub struct PlatformVersion(String);
52
53impl PlatformVersion {
54 pub fn to_semver(&self) -> semver::Version {
56 semver::Version::parse(&self.0)
63 .expect("Broken Invariant: PlatformVersion can only be constructed with Semver")
64 }
65}
66
67impl From<semver::Version> for PlatformVersion {
68 fn from(version: semver::Version) -> Self {
69 Self(version.to_string())
70 }
71}
72
73impl Default for PlatformVersion {
74 fn default() -> Self {
75 Self(semver::Version::new(0, 0, 0).to_string())
76 }
77}
78
79impl Decoder for PlatformVersion {
80 fn decode<T>(&mut self, src: &mut T, version: i16) -> Result<(), IoError>
82 where
83 T: Buf,
84 {
85 let mut string = String::default();
87 string.decode(src, version)?;
88
89 let _version = semver::Version::parse(&string).map_err(|_| {
91 IoError::new(
92 ErrorKind::InvalidData,
93 "PlatformVersion is not valid semver",
94 )
95 })?;
96
97 self.0 = string;
99 Ok(())
100 }
101}
102
103impl Encoder for PlatformVersion {
104 fn write_size(&self, version: Version) -> usize {
105 self.0.write_size(version)
106 }
107
108 fn encode<T>(&self, dest: &mut T, version: Version) -> Result<(), IoError>
109 where
110 T: BufMut,
111 {
112 self.0.encode(dest, version)
113 }
114}
115
116#[cfg(test)]
117mod tests {
118 use super::*;
119
120 #[test]
121 fn test_encode_platform_version() {
122 let version = semver::Version::parse("1.2.3-alpha.4+56789").unwrap();
123 let version_string = version.to_string();
124 let platform_version = PlatformVersion::from(version);
125
126 let mut version_string_buffer: Vec<u8> = vec![];
128 version_string
129 .encode(&mut version_string_buffer, 0)
130 .unwrap();
131 let mut platform_version_buffer: Vec<u8> = vec![];
132 platform_version
133 .encode(&mut platform_version_buffer, 0)
134 .unwrap();
135 assert_eq!(version_string_buffer, platform_version_buffer);
136
137 let mut decoded_platform_version = PlatformVersion::default();
139 decoded_platform_version
140 .decode(&mut (&*platform_version_buffer), 0)
141 .unwrap();
142 assert_eq!(platform_version, decoded_platform_version);
143 }
144
145 #[test]
146 fn test_encode_decode_api_versions_response() {
147 fn api_versions() -> ApiVersionsResponse {
148 let version = semver::Version::parse("0.1.2-alpha.3+4567").unwrap();
149 let platform_version = PlatformVersion::from(version);
150 ApiVersionsResponse {
151 error_code: ErrorCode::None,
152 api_keys: vec![],
153 platform_version,
154 }
155 }
156
157 let api_version = api_versions();
158 let mut api_versions_buffer: Vec<u8> = vec![];
159 api_version.encode(&mut api_versions_buffer, 0).unwrap();
160
161 let mut decoded_api_version = ApiVersionsResponse::default();
162 decoded_api_version
163 .decode(&mut (&*api_versions_buffer), 0)
164 .unwrap();
165
166 assert_eq!(api_version, decoded_api_version);
167 }
168}