//! A pure rust replacement for the [miniz](https://github.com/richgel999/miniz)
//! DEFLATE/zlib encoder/decoder.
//! The plan for this crate is to be used as a back-end for the
//! [flate2](https://github.com/alexcrichton/flate2-rs) crate and eventually remove the
//! need to depend on a C library.
//!
//! # Usage
//! ## Simple compression/decompression:
//! ``` rust
//!
//! use miniz_oxide::inflate::decompress_to_vec;
//! use miniz_oxide::deflate::compress_to_vec;
//!
//! fn roundtrip(data: &[u8]) {
//!     let compressed = compress_to_vec(data, 6);
//!     let decompressed = decompress_to_vec(compressed.as_slice()).expect("Failed to decompress!");
//! #   let _ = decompressed;
//! }
//!
//! # roundtrip(b"Test_data test data lalalal blabla");
//!
//! ```

#![forbid(unsafe_code)]
#![no_std]

extern crate alloc;

pub mod deflate;
pub mod inflate;
mod shared;

pub use crate::shared::update_adler32 as mz_adler32_oxide;
pub use crate::shared::{MZ_ADLER32_INIT, MZ_DEFAULT_WINDOW_BITS};

/// A list of flush types.
///
/// See <http://www.bolet.org/~pornin/deflate-flush.html> for more in-depth info.
#[repr(i32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum MZFlush {
    /// Don't force any flushing.
    /// Used when more input data is expected.
    None = 0,
    /// Zlib partial flush.
    /// Currently treated as [`Sync`].
    Partial = 1,
    /// Finish compressing the currently buffered data, and output an empty raw block.
    /// Has no use in decompression.
    Sync = 2,
    /// Same as [`Sync`], but resets the compression dictionary so that further compressed
    /// data does not depend on data compressed before the flush.
    ///
    /// Has no use in decompression, and is an error to supply in that case.
    Full = 3,
    /// Attempt to flush the remaining data and end the stream.
    Finish = 4,
    /// Not implemented.
    Block = 5,
}

impl MZFlush {
    /// Create an MZFlush value from an integer value.
    ///
    /// Returns `MZError::Param` on invalid values.
    pub fn new(flush: i32) -> Result<Self, MZError> {
        match flush {
            0 => Ok(MZFlush::None),
            1 | 2 => Ok(MZFlush::Sync),
            3 => Ok(MZFlush::Full),
            4 => Ok(MZFlush::Finish),
            _ => Err(MZError::Param),
        }
    }
}

/// A list of miniz successful status codes.
///
/// These are emitted as the [`Ok`] side of a [`MZResult`] in the [`StreamResult`] returned from
/// [`deflate::stream::deflate()`] or [`inflate::stream::inflate()`].
#[repr(i32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum MZStatus {
    /// Operation succeeded.
    ///
    /// Some data was decompressed or compressed; see the byte counters in the [`StreamResult`] for
    /// details.
    Ok = 0,

    /// Operation succeeded and end of deflate stream was found.
    ///
    /// X-ref [`TINFLStatus::Done`][inflate::TINFLStatus::Done] or
    /// [`TDEFLStatus::Done`][deflate::core::TDEFLStatus::Done] for `inflate` or `deflate`
    /// respectively.
    StreamEnd = 1,

    /// Unused
    NeedDict = 2,
}

/// A list of miniz failed status codes.
///
/// These are emitted as the [`Err`] side of a [`MZResult`] in the [`StreamResult`] returned from
/// [`deflate::stream::deflate()`] or [`inflate::stream::inflate()`].
#[repr(i32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum MZError {
    /// Unused
    ErrNo = -1,

    /// General stream error.
    ///
    /// See [`inflate::stream::inflate()`] docs for details of how it can occur there.
    ///
    /// See [`deflate::stream::deflate()`] docs for how it can in principle occur there, though it's
    /// believed impossible in practice.
    Stream = -2,

    /// Error in inflation; see [`inflate::stream::inflate()`] for details.
    ///
    /// Not returned from [`deflate::stream::deflate()`].
    Data = -3,

    /// Unused
    Mem = -4,

    /// Buffer-related error.
    ///
    /// See the docs of [`deflate::stream::deflate()`] or [`inflate::stream::inflate()`] for details
    /// of when it would trigger in the one you're using.
    Buf = -5,

    /// Unused
    Version = -6,

    /// Bad parameters.
    ///
    /// This can be returned from [`deflate::stream::deflate()`] in the case of bad parameters.  See
    /// [`TDEFLStatus::BadParam`][deflate::core::TDEFLStatus::BadParam].
    Param = -10_000,
}

/// How compressed data is wrapped.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum DataFormat {
    /// Wrapped using the [zlib](http://www.zlib.org/rfc-zlib.html) format.
    Zlib,
    /// Zlib wrapped but ignore and don't compute the adler32 checksum.
    /// Currently only used for inflate, behaves the same as Zlib for compression.
    ZLibIgnoreChecksum,
    /// Raw DEFLATE.
    Raw,
}

impl DataFormat {
    pub(crate) fn from_window_bits(window_bits: i32) -> DataFormat {
        if window_bits > 0 {
            DataFormat::Zlib
        } else {
            DataFormat::Raw
        }
    }

    pub(crate) fn to_window_bits(self) -> i32 {
        match self {
            DataFormat::Zlib | DataFormat::ZLibIgnoreChecksum => shared::MZ_DEFAULT_WINDOW_BITS,
            DataFormat::Raw => -shared::MZ_DEFAULT_WINDOW_BITS,
        }
    }
}

/// `Result` alias for all miniz status codes both successful and failed.
pub type MZResult = Result<MZStatus, MZError>;

/// A structure containg the result of a call to the inflate or deflate streaming functions.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct StreamResult {
    /// The number of bytes consumed from the input slice.
    pub bytes_consumed: usize,
    /// The number of bytes written to the output slice.
    pub bytes_written: usize,
    /// The return status of the call.
    pub status: MZResult,
}

impl StreamResult {
    #[inline]
    pub(crate) const fn error(error: MZError) -> StreamResult {
        StreamResult {
            bytes_consumed: 0,
            bytes_written: 0,
            status: Err(error),
        }
    }
}

impl core::convert::From<StreamResult> for MZResult {
    fn from(res: StreamResult) -> Self {
        res.status
    }
}

impl core::convert::From<&StreamResult> for MZResult {
    fn from(res: &StreamResult) -> Self {
        res.status
    }
}
