Skip to content

Commit

Permalink
Add support for no_std environments
Browse files Browse the repository at this point in the history
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: dfrg/swash#4

This is a breaking change, as anyone who is already importing yazi with
"default-features = false" and using the From<io::Error> impl on
yazi::Error will have their build break after this commit.

Signed-off-by: John Nunley <[email protected]>
  • Loading branch information
notgull committed Sep 5, 2023
1 parent bc125e5 commit c703097
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 7 deletions.
4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ repository = "https://github.com/dfrg/yazi"
homepage = "https://github.com/dfrg/yazi"
readme = "README.md"

[dependencies]
[features]
default = ["std"]
std = []
10 changes: 9 additions & 1 deletion src/decode.rs
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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,
Expand Down Expand Up @@ -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<usize> {
match self.ctx.inflate(buf, &mut self.sink, false) {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -1131,12 +1137,14 @@ impl<'a> Sink for BufSink<'a> {
}
}

#[cfg(feature = "std")]
struct WriterSink<W> {
writer: W,
ring: RingBuffer,
written: u64,
}

#[cfg(feature = "std")]
impl<W: Write> Sink for WriterSink<W> {
fn written(&self) -> u64 {
self.written
Expand Down
17 changes: 12 additions & 5 deletions src/encode.rs
Original file line number Diff line number Diff line change
@@ -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)]
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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<usize> {
match self.ctx.deflate(buf, &mut self.sink, false) {
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -1475,6 +1479,7 @@ impl<'a> Sink for VecSink<'a> {
}
}

#[cfg(feature = "std")]
struct WriterSink<W> {
writer: W,
buffer: [u8; OUT_BUFFER_SIZE],
Expand All @@ -1484,6 +1489,7 @@ struct WriterSink<W> {
written: u64,
}

#[cfg(feature = "std")]
impl<W> WriterSink<W> {
fn new(writer: W) -> Self {
Self {
Expand All @@ -1497,6 +1503,7 @@ impl<W> WriterSink<W> {
}
}

#[cfg(feature = "std")]
impl<W: Write> Sink for WriterSink<W> {
#[inline(always)]
fn put_bits(&mut self, bits: u32, len: u32) -> Result<(), Error> {
Expand Down
10 changes: 10 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,9 +230,14 @@
//! decompressor is based on the techniques in libdeflate (<https://github.com/ebiggers/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};
Expand All @@ -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<io::Error> for Error {
fn from(error: io::Error) -> Self {
Self::Io(error)
Expand Down Expand Up @@ -315,6 +324,7 @@ impl Default for Adler32 {
#[cfg(test)]
mod tests {
use super::*;
use alloc::vec::Vec;

fn generate_bytes() -> Vec<u8> {
const BYTES: &[u8; 26] = b"abcdefghijklmnopqrstuvwxyz";
Expand Down

0 comments on commit c703097

Please sign in to comment.