use flate2::write::GzEncoder;
use flate2::read::GzDecoder;
use flate2::Compression;
use serde::{Serialize, Deserialize};
use crate::blocker::Blocker;
pub const VERSION: &'static str = env!("CARGO_PKG_VERSION");
pub struct Wrapper<'a> {
pub wrapped: &'a Blocker
}
pub struct Unwrappable {
pub wrapped: Box<Blocker>
}
impl<'a> serde::Serialize for Wrapper<'a> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
#[derive(Serialize)]
struct EncodedBlocker<'b> {
#[serde(rename = "manifest-version")]
manifest_version: &'b str,
blocker: &'b Vec<u8>
}
let mut gz = GzEncoder::new(Vec::new(), Compression::default());
bincode::serialize_into(&mut gz, &self)
.or_else(|e| {
Err(D::Error::invalid_value(::serde::de::Unexpected::Other("Failed to serialize to bincode"), &e.to_string().as_str()))
})?;
let compressed = gz.finish().unwrap();
.or_else(|e| {
Err(D::Error::invalid_value(::serde::de::Unexpected::Other("Failed to finish Gzip encoding"), &e.to_string().as_str()))
})?;
let output = EncodedBlocker {
manifest_version: VERSION,
blocker: &compressed,
};
output.serialize(serializer)
}
}
impl<'de> serde::Deserialize<'de> for Unwrappable {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
use serde::de::Error;
#[derive(Deserialize)]
struct EncodedBlocker {
#[serde(rename = "manifest-version")]
pub manifest_version: String,
pub blocker: Vec<u8>
}
let input = EncodedBlocker::deserialize(deserializer)?;
if input.manifest_version != VERSION {
return Err(D::Error::invalid_value(
::serde::de::Unexpected::Str(&input.manifest_version), &VERSION
));
}
let gz = GzDecoder::new(&input.blocker[..]);
let blocker = bincode::deserialize_from(gz)
.or_else(|e| {
Err(D::Error::invalid_value(::serde::de::Unexpected::Other("Failed to parse bincode formatted data"), &e.to_string().as_str()))
})?;
Ok(Unwrappable {
wrapped: Box::new(blocker)
})
}
}