use std::io::{Error as IoError, ErrorKind};
use fluvio_protocol::{Encoder, Version, Decoder};
use fluvio_protocol::bytes::{BufMut, Buf};
use crate::ErrorCode;
use crate::api::Request;
use crate::derive::{Decode, Encode};
pub const VERSIONS_API_KEY: u16 = 18;
#[derive(Decode, Encode, Default, Debug)]
pub struct ApiVersionsRequest {}
impl Request for ApiVersionsRequest {
const API_KEY: u16 = VERSIONS_API_KEY;
type Response = ApiVersionsResponse;
}
pub type ApiVersions = Vec<ApiVersionKey>;
#[derive(Decode, Encode, Default, Debug, PartialEq)]
pub struct ApiVersionsResponse {
pub error_code: ErrorCode,
pub api_keys: ApiVersions,
pub platform_version: PlatformVersion,
}
#[derive(Decode, Encode, Default, Clone, Debug, PartialEq)]
pub struct ApiVersionKey {
pub api_key: i16,
pub min_version: i16,
pub max_version: i16,
}
#[derive(Debug, PartialEq)]
pub struct PlatformVersion(String);
impl PlatformVersion {
pub fn to_semver(&self) -> semver::Version {
semver::Version::parse(&self.0)
.expect("Broken Invariant: PlatformVersion can only be constructed with Semver")
}
}
impl From<semver::Version> for PlatformVersion {
fn from(version: semver::Version) -> Self {
Self(version.to_string())
}
}
impl Default for PlatformVersion {
fn default() -> Self {
Self(semver::Version::new(0, 0, 0).to_string())
}
}
impl Decoder for PlatformVersion {
fn decode<T>(&mut self, src: &mut T, version: i16) -> Result<(), IoError>
where
T: Buf,
{
let mut string = String::default();
string.decode(src, version)?;
let _version = semver::Version::parse(&string).map_err(|_| {
IoError::new(
ErrorKind::InvalidData,
"PlatformVersion is not valid semver",
)
})?;
self.0 = string;
Ok(())
}
}
impl Encoder for PlatformVersion {
fn write_size(&self, version: Version) -> usize {
self.0.write_size(version)
}
fn encode<T>(&self, dest: &mut T, version: Version) -> Result<(), IoError>
where
T: BufMut,
{
self.0.encode(dest, version)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_encode_platform_version() {
let version = semver::Version::parse("1.2.3-alpha.4+56789").unwrap();
let version_string = version.to_string();
let platform_version = PlatformVersion::from(version);
let mut version_string_buffer: Vec<u8> = vec![];
version_string
.encode(&mut version_string_buffer, 0)
.unwrap();
let mut platform_version_buffer: Vec<u8> = vec![];
platform_version
.encode(&mut platform_version_buffer, 0)
.unwrap();
assert_eq!(version_string_buffer, platform_version_buffer);
let mut decoded_platform_version = PlatformVersion::default();
decoded_platform_version
.decode(&mut (&*platform_version_buffer), 0)
.unwrap();
assert_eq!(platform_version, decoded_platform_version);
}
#[test]
fn test_encode_decode_api_versions_response() {
fn api_versions() -> ApiVersionsResponse {
let version = semver::Version::parse("0.1.2-alpha.3+4567").unwrap();
let platform_version = PlatformVersion::from(version);
ApiVersionsResponse {
error_code: ErrorCode::None,
api_keys: vec![],
platform_version,
}
}
let api_version = api_versions();
let mut api_versions_buffer: Vec<u8> = vec![];
api_version.encode(&mut api_versions_buffer, 0).unwrap();
let mut decoded_api_version = ApiVersionsResponse::default();
decoded_api_version
.decode(&mut (&*api_versions_buffer), 0)
.unwrap();
assert_eq!(api_version, decoded_api_version);
}
}