High-level interface

It is now time to design a higher-level interface to the zstd library. Our goal is to no longer expose any unsafe function to the user of our library.

Exercise 3.a: Create a new library crate named zstd inside the cargo workspace.

⚠️ For the rest of this page, everything happens in the zstd crate.

Exercise 3.b: Make zstd-sys a dependency of the zstd crate. You may have to lookup how to define a dependency by its path (which will be relative to the zstd crate).

Exercise 3.c: Write a compress_buffer() function with the following signature:

pub fn compress_buffer(src: &[u8], dst: &mut [u8], level: i32) -> Result<usize, ZstdError> {
    // ...
}

ZstdError is an error type that you will define yourself. You may use the thiserror crate if you wish.

Exercise 4.d: Write a decompress_buffer() function with the following signature:

pub fn decompress_buffer(src: &[u8], dst: &mut [u8]) -> Result<usize, ZstdError> {
    // ...
}

Exercise 4.e: Write amax_compressed_size() function with the following signature:

pub fn max_compressed_size(size: usize) -> usize {
    // ...
}

Exercise 4.f: write a decompressed_size() function with the following signature:

pub fn decompressed_size(src: &[u8]) -> Result<usize, ZstdError> {
    // ...
}

Exercise 4.g: Add one or more tests, as you did for the zstd-sys crate, to test that those functions work as expected.