From c703097da21b3a0151c148f2c94a64c933232267 Mon Sep 17 00:00:00 2001 From: John Nunley Date: Tue, 5 Sep 2023 08:05:30 -0700 Subject: [PATCH] Add support for no_std environments This commit adds a default "std" feature that can be disabled to run this crate in no_std environments. This allows for Zlib compression or decompression to happen on embedded systems. Rel: https://github.com/dfrg/swash/issues/4 This is a breaking change, as anyone who is already importing yazi with "default-features = false" and using the From impl on yazi::Error will have their build break after this commit. Signed-off-by: John Nunley --- Cargo.toml | 4 +++- src/decode.rs | 10 +++++++++- src/encode.rs | 17 ++++++++++++----- src/lib.rs | 10 ++++++++++ 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 04df8b5..067aed1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,4 +11,6 @@ repository = "https://github.com/dfrg/yazi" homepage = "https://github.com/dfrg/yazi" readme = "README.md" -[dependencies] +[features] +default = ["std"] +std = [] diff --git a/src/decode.rs b/src/decode.rs index 164f5a2..ea6daff 100644 --- a/src/decode.rs +++ b/src/decode.rs @@ -1,6 +1,10 @@ //! RFC 1590 decompression implementation. use super::{Error, Format}; +use alloc::boxed::Box; +use alloc::vec::Vec; + +#[cfg(feature = "std")] use std::io::{self, Write}; /// Stateful context for decompression. @@ -27,6 +31,7 @@ impl Decoder { } /// Creates a decoder stream that will write into the specified writer. + #[cfg(feature = "std")] pub fn stream<'a, W: Write>( &'a mut self, writer: &'a mut W, @@ -125,6 +130,7 @@ impl<'a, S: Sink> Drop for DecoderStream<'a, S> { } } +#[cfg(feature = "std")] impl<'a, S: Sink> Write for DecoderStream<'a, S> { fn write(&mut self, buf: &[u8]) -> io::Result { match self.ctx.inflate(buf, &mut self.sink, false) { @@ -942,7 +948,7 @@ impl Bits { let len = bytes.len(); let mut i = 0; while (i + 4) <= len { - use std::convert::TryInto; + use core::convert::TryInto; let v = u32::from_le_bytes((&bytes[i..i + 4]).try_into().unwrap()) as u64; self.bit_buffer |= v << self.bits_in; self.bits_in += 32; @@ -1131,12 +1137,14 @@ impl<'a> Sink for BufSink<'a> { } } +#[cfg(feature = "std")] struct WriterSink { writer: W, ring: RingBuffer, written: u64, } +#[cfg(feature = "std")] impl Sink for WriterSink { fn written(&self) -> u64 { self.written diff --git a/src/encode.rs b/src/encode.rs index 5c8cb61..523b3d7 100644 --- a/src/encode.rs +++ b/src/encode.rs @@ -1,10 +1,12 @@ //! RFC 1590 compression implementation. use super::{Adler32, Error, Format}; -use std::{ - convert::TryInto, - io::{self, Write}, -}; +use alloc::boxed::Box; +use alloc::vec::Vec; +use core::convert::TryInto; + +#[cfg(feature = "std")] +use std::io::{self, Write}; /// The level of compression-- a compromise between speed and size. #[derive(Copy, Clone, PartialEq, Debug)] @@ -142,6 +144,7 @@ impl Encoder { } /// Creates an encoder stream that will write into the specified writer. + #[cfg(feature = "std")] pub fn stream<'a, W: Write>( &'a mut self, writer: &'a mut W, @@ -235,6 +238,7 @@ impl<'a, S: Sink> Drop for EncoderStream<'a, S> { } } +#[cfg(feature = "std")] impl<'a, S: Sink> Write for EncoderStream<'a, S> { fn write(&mut self, buf: &[u8]) -> io::Result { match self.ctx.deflate(buf, &mut self.sink, false) { @@ -927,7 +931,7 @@ mod huffman { new_syms[offsets[j] as usize] = *sym; offsets[j] += 1; } - std::mem::swap(&mut cur_syms, &mut new_syms); + core::mem::swap(&mut cur_syms, &mut new_syms); } cur_syms } @@ -1475,6 +1479,7 @@ impl<'a> Sink for VecSink<'a> { } } +#[cfg(feature = "std")] struct WriterSink { writer: W, buffer: [u8; OUT_BUFFER_SIZE], @@ -1484,6 +1489,7 @@ struct WriterSink { written: u64, } +#[cfg(feature = "std")] impl WriterSink { fn new(writer: W) -> Self { Self { @@ -1497,6 +1503,7 @@ impl WriterSink { } } +#[cfg(feature = "std")] impl Sink for WriterSink { #[inline(always)] fn put_bits(&mut self, bits: u32, len: u32) -> Result<(), Error> { diff --git a/src/lib.rs b/src/lib.rs index ba6b245..6528568 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -230,9 +230,14 @@ //! decompressor is based on the techniques in libdeflate () //! by Eric Biggers. +#![cfg_attr(not(feature = "std"), no_std)] + +extern crate alloc; + mod decode; mod encode; +#[cfg(feature = "std")] use std::io; pub use decode::{decompress, Decoder, DecoderStream}; @@ -259,9 +264,13 @@ pub enum Error { /// Attempt to write into a finished stream. Finished, /// A system I/O error. + /// + /// Only available with the `std` feature enabled. + #[cfg(feature = "std")] Io(io::Error), } +#[cfg(feature = "std")] impl From for Error { fn from(error: io::Error) -> Self { Self::Io(error) @@ -315,6 +324,7 @@ impl Default for Adler32 { #[cfg(test)] mod tests { use super::*; + use alloc::vec::Vec; fn generate_bytes() -> Vec { const BYTES: &[u8; 26] = b"abcdefghijklmnopqrstuvwxyz";