mod reader;
mod writer;
pub use {reader::*, writer::*};
use std::num::NonZeroU8;
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
pub enum Compression {
Null,
#[cfg(feature = "deflate")]
Deflate {
level: CompressionLevel,
},
#[cfg(feature = "bzip2")]
Bzip2 {
level: CompressionLevel,
},
#[cfg(feature = "snappy")]
Snappy,
#[cfg(feature = "xz")]
Xz {
level: CompressionLevel,
},
#[cfg(feature = "zstandard")]
Zstandard {
level: CompressionLevel,
},
}
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub struct CompressionLevel {
repr: NonZeroU8,
}
impl CompressionLevel {
pub const fn new(mut level: u8) -> Self {
if level == u8::MAX {
level -= 1;
}
match NonZeroU8::new(level) {
Some(n) => Self { repr: n },
None => panic!("Compression level must be greater than 0"),
}
}
pub const fn default() -> Self {
Self {
repr: match NonZeroU8::new(u8::MAX) {
Some(nonzero) => nonzero,
None => unreachable!(),
},
}
}
#[allow(unused)]
fn clip(mut self, high: u8) -> Self {
if self.repr.get() != u8::MAX {
self.repr = self.repr.min(NonZeroU8::new(high).expect(
"Highest compression level for \
algorithm should be greater than zero",
))
}
self
}
#[allow(unused)]
fn instantiate<T: Default, C: From<u8>, F: FnOnce(C) -> T>(self, f: F) -> T {
match self.repr.get() {
u8::MAX => T::default(),
specified_compression_level => f(specified_compression_level.into()),
}
}
#[allow(unused)]
fn instantiate_nb<C: From<u8>>(self, default: C) -> C {
match self.repr.get() {
u8::MAX => default,
specified_compression_level => specified_compression_level.into(),
}
}
}
impl Default for CompressionLevel {
fn default() -> Self {
CompressionLevel::default()
}
}
impl std::fmt::Debug for CompressionLevel {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self.repr.get() {
u8::MAX => write!(f, "Default"),
_ => write!(f, "{}", self.repr),
}
}
}
impl Compression {
fn codec(&self) -> CompressionCodec {
match self {
Compression::Null => CompressionCodec::Null,
#[cfg(feature = "deflate")]
Compression::Deflate { .. } => CompressionCodec::Deflate,
#[cfg(feature = "bzip2")]
Compression::Bzip2 { .. } => CompressionCodec::Bzip2,
#[cfg(feature = "snappy")]
Compression::Snappy => CompressionCodec::Snappy,
#[cfg(feature = "xz")]
Compression::Xz { .. } => CompressionCodec::Xz,
#[cfg(feature = "zstandard")]
Compression::Zstandard { .. } => CompressionCodec::Zstandard,
}
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, serde_derive::Deserialize, serde_derive::Serialize)]
#[serde(rename_all = "kebab-case")]
#[non_exhaustive]
enum CompressionCodec {
Null,
#[cfg(feature = "deflate")]
Deflate,
#[cfg(feature = "bzip2")]
Bzip2,
#[cfg(feature = "snappy")]
Snappy,
#[cfg(feature = "xz")]
Xz,
#[cfg(feature = "zstandard")]
Zstandard,
}
const HEADER_CONST: [u8; 4] = [b'O', b'b', b'j', 1u8];
#[derive(serde_derive::Deserialize, serde_derive::Serialize)]
struct Metadata<S, M> {
#[serde(rename = "avro.schema")]
schema: S,
#[serde(rename = "avro.codec")]
codec: CompressionCodec,
#[serde(flatten)]
user_metadata: M,
}
const METADATA_SCHEMA: crate::schema::self_referential::NodeRef<'static> =
crate::schema::self_referential::NodeRef::from_static(
&crate::schema::self_referential::SchemaNode::Map(
crate::schema::self_referential::NodeRef::from_static(
&crate::schema::self_referential::SchemaNode::Bytes,
),
),
);
#[test]
fn compression_codec_serializes_properly() {
let codec = CompressionCodec::Null;
let serialized = serde_json::to_string(&codec).unwrap();
assert_eq!(serialized, "\"null\"");
#[cfg(feature = "deflate")]
{
let codec = CompressionCodec::Deflate;
let serialized = serde_json::to_string(&codec).unwrap();
assert_eq!(serialized, "\"deflate\"");
}
#[cfg(feature = "bzip2")]
{
let codec = CompressionCodec::Bzip2;
let serialized = serde_json::to_string(&codec).unwrap();
assert_eq!(serialized, "\"bzip2\"");
}
#[cfg(feature = "snappy")]
{
let codec = CompressionCodec::Snappy;
let serialized = serde_json::to_string(&codec).unwrap();
assert_eq!(serialized, "\"snappy\"");
}
#[cfg(feature = "xz")]
{
let codec = CompressionCodec::Xz;
let serialized = serde_json::to_string(&codec).unwrap();
assert_eq!(serialized, "\"xz\"");
}
#[cfg(feature = "zstandard")]
{
let codec = CompressionCodec::Zstandard;
let serialized = serde_json::to_string(&codec).unwrap();
assert_eq!(serialized, "\"zstandard\"");
}
}