use crate::response::base::{
Dec4, Error, Hex16, Record as BaseRecord, Response as BaseResponse, Result, String0,
};
#[derive(Debug, PartialEq)]
pub struct Record {
pub region: String0,
pub build_config: Hex16,
pub cdn_config: Hex16,
pub key_ring: Option<Hex16>,
pub build_id: Dec4,
pub versions_name: String0,
pub product_config: Hex16,
}
impl<'input> TryFrom<BaseRecord<'_, 'input>> for Record {
type Error = Error;
fn try_from(record: BaseRecord<'_, 'input>) -> Result<Self> {
let region = (&record
.get_field_by_header_name("Region")
.ok_or(Error::ExpectedField("Region"))?)
.try_into()?;
let build_config = (&record
.get_field_by_header_name("BuildConfig")
.ok_or(Error::ExpectedField("BuildConfig"))?)
.try_into()?;
let cdn_config = (&record
.get_field_by_header_name("CDNConfig")
.ok_or(Error::ExpectedField("CDNConfig"))?)
.try_into()?;
let key_ring = (&record
.get_field_by_header_name("KeyRing")
.ok_or(Error::ExpectedField("KeyRing"))?)
.try_into()?;
let build_id = (&record
.get_field_by_header_name("BuildId")
.ok_or(Error::ExpectedField("BuildId"))?)
.try_into()?;
let versions_name = (&record
.get_field_by_header_name("VersionsName")
.ok_or(Error::ExpectedField("VersionsName"))?)
.try_into()?;
let product_config = (&record
.get_field_by_header_name("ProductConfig")
.ok_or(Error::ExpectedField("ProductConfig"))?)
.try_into()?;
Ok(Self {
region,
build_config,
cdn_config,
key_ring,
build_id,
versions_name,
product_config,
})
}
}
#[derive(Debug, PartialEq)]
pub struct Response {
pub seqn: u32,
pub records: Vec<Record>,
}
impl<'input> TryFrom<BaseResponse<'input>> for Response {
type Error = Error;
fn try_from(response: BaseResponse<'input>) -> Result<Self> {
Ok(Self {
seqn: response.seqn,
records: response
.iter_records()
.map(TryInto::try_into)
.collect::<Result<_>>()?,
})
}
}
impl<'input> TryFrom<&'input str> for Response {
type Error = Error;
fn try_from(input: &'input str) -> Result<Self> {
let response = BaseResponse::try_from(input)?;
Response::try_from(response)
}
}
impl<'input> TryFrom<&'input [u8]> for Response {
type Error = Error;
fn try_from(input: &'input [u8]) -> Result<Self> {
let response = BaseResponse::try_from(input)?;
Response::try_from(response)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_versions_response() {
let input = "Region!STRING:0|BuildConfig!HEX:16|CDNConfig!HEX:16|KeyRing!HEX:16|BuildId!DEC:4|VersionsName!String:0|ProductConfig!HEX:16\n\
## seqn = 2118468\n\
us|47e9e06f8371afb141e22614a912acc8|74093d42ce367c7a67f2831dbf64088d||53584|10.2.5.53584|53020d32e1a25648c8e1eafd5771935f\n\
eu|47e9e06f8371afb141e22614a912acc8|74093d42ce367c7a67f2831dbf64088d||53584|10.2.5.53584|53020d32e1a25648c8e1eafd5771935f";
let versions_response = Response::try_from(input).unwrap();
assert_eq!(
versions_response,
Response {
seqn: 2_118_468,
records: vec![
Record {
region: "us".to_owned(),
build_config: [
0x47, 0xe9, 0xe0, 0x6f, 0x83, 0x71, 0xaf, 0xb1, 0x41, 0xe2, 0x26, 0x14,
0xa9, 0x12, 0xac, 0xc8
],
cdn_config: [
0x74, 0x09, 0x3d, 0x42, 0xce, 0x36, 0x7c, 0x7a, 0x67, 0xf2, 0x83, 0x1d,
0xbf, 0x64, 0x08, 0x8d
],
key_ring: None,
build_id: 53584,
versions_name: "10.2.5.53584".to_owned(),
product_config: [
0x53, 0x2, 0xd, 0x32, 0xe1, 0xa2, 0x56, 0x48, 0xc8, 0xe1, 0xea, 0xfd,
0x57, 0x71, 0x93, 0x5f
]
},
Record {
region: "eu".to_owned(),
build_config: [
0x47, 0xe9, 0xe0, 0x6f, 0x83, 0x71, 0xaf, 0xb1, 0x41, 0xe2, 0x26, 0x14,
0xa9, 0x12, 0xac, 0xc8
],
cdn_config: [
0x74, 0x09, 0x3d, 0x42, 0xce, 0x36, 0x7c, 0x7a, 0x67, 0xf2, 0x83, 0x1d,
0xbf, 0x64, 0x08, 0x8d
],
key_ring: None,
build_id: 53584,
versions_name: "10.2.5.53584".to_owned(),
product_config: [
0x53, 0x2, 0xd, 0x32, 0xe1, 0xa2, 0x56, 0x48, 0xc8, 0xe1, 0xea, 0xfd,
0x57, 0x71, 0x93, 0x5f
]
}
]
}
);
}
}