1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
extern crate cloudflare_zlib_sys;
use std::fmt;

pub use cloudflare_zlib_sys::{Z_NO_COMPRESSION, Z_BEST_SPEED,
    Z_BEST_COMPRESSION, Z_DEFAULT_COMPRESSION, Z_FILTERED,
    Z_HUFFMAN_ONLY, Z_RLE, Z_FIXED, Z_DEFAULT_STRATEGY};

mod def;
pub use def::*;
mod inf;
pub use inf::*;
use std::os::raw::c_int;

/// If `false`, this crate won't work
pub fn is_supported() -> bool {
    #[cfg(target_arch = "x86_64")]
    {
        if is_x86_feature_detected!("sse4.2") && is_x86_feature_detected!("pclmulqdq") {
            return true;
        }
    }
    #[cfg(target_arch = "aarch64")]
    {
        if is_arm_feature_detected!("neon") && is_arm_feature_detected!("crc") {
            return true;
        }
    }
    false
}

#[derive(Debug)]
/// See zlib's documentation for exact meaning of these errors.
pub enum ZError {
    /// `Z_STREAM_END`
    StreamEnd,
    /// `Z_NEED_DICT`
    NeedDict,
    /// `Z_ERRNO`
    Errno,
    /// `Z_STREAM_ERROR`
    StreamError,
    /// `Z_DATA_ERROR`
    DataError,
    /// `Z_MEM_ERROR`
    MemError,
    /// `Z_BUF_ERROR`
    BufError,
    /// `Z_VERSION_ERROR`
    VersionError,
    /// When `compress_with_limit` was used, and limit was exceeded. Contains size compressed so far.
    DeflatedDataTooLarge(usize),
    /// Unknown error. Shouldn't happen.
    OtherError(c_int),
    /// It won't work on this computer
    ///
    /// Only recent 64-bit Intel and ARM CPUs are supported.
    IncompatibleCPU,
}

impl ZError {
    fn new(code: c_int) -> Self {
        match code {
            1 => ZError::StreamEnd,
            2 => ZError::NeedDict,
            -1 => ZError::Errno,
            -2 => ZError::StreamError,
            -3 => ZError::DataError,
            -4 => ZError::MemError,
            -5 => ZError::BufError,
            -6 => ZError::VersionError,
            other => ZError::OtherError(other),
        }
    }
}

impl fmt::Display for ZError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        <Self as fmt::Debug>::fmt(self, f)
    }
}

impl std::error::Error for ZError {
    fn description(&self) -> &str {"zlib error"}
}