few more fixes + clippy
This commit is contained in:
parent
4f314b45f2
commit
a2b6cc4f5c
17
README.md
17
README.md
|
@ -19,11 +19,24 @@ GNU Extensions such as sparse files, incremental archives, and long filename ext
|
|||
[This link](https://www.gnu.org/software/tar/manual/html_section/Formats.html) gives a good overview over possible
|
||||
archive formats and their limitations.
|
||||
|
||||
## Example
|
||||
```rust
|
||||
fn main() {
|
||||
// log: not mandatory
|
||||
std::env::set_var("RUST_LOG", "trace");
|
||||
env_logger::init();
|
||||
|
||||
// also works in no_std environment
|
||||
let archive = include_bytes!("../tests/gnu_tar_default.tar");
|
||||
let archive = TarArchive::new(archive);
|
||||
let entries = archive.entries().collect::<Vec<_>>();
|
||||
println!("{:#?}", entries);
|
||||
}
|
||||
```
|
||||
|
||||
## Compression
|
||||
If your tar file is compressed, e.g. bei `gzip`, you need to uncompress the bytes first (e.g. by a *deflate* algorithm),
|
||||
before
|
||||
If your tar file is compressed, e.g. bei `.tar.gz`/`gzip`, you need to uncompress the bytes first
|
||||
(e.g. by a *gzip* library). Afterwards, this crate can read and write the Tar archive format from the bytes.
|
||||
|
||||
## MSRV
|
||||
The MSRV is 1.51.0 stable.
|
||||
|
|
|
@ -30,7 +30,7 @@ use core::fmt::{Debug, Formatter};
|
|||
use core::ptr;
|
||||
use core::str::FromStr;
|
||||
|
||||
/// Describes an entry in a archive.
|
||||
/// Describes an entry in an archive.
|
||||
/// Currently only supports files but no directories.
|
||||
pub struct ArchiveEntry<'a> {
|
||||
filename: ArrayString<100>,
|
||||
|
@ -40,7 +40,7 @@ pub struct ArchiveEntry<'a> {
|
|||
|
||||
#[allow(unused)]
|
||||
impl<'a> ArchiveEntry<'a> {
|
||||
pub fn new(filename: ArrayString<100>, data: &'a [u8]) -> Self {
|
||||
pub const fn new(filename: ArrayString<100>, data: &'a [u8]) -> Self {
|
||||
ArchiveEntry {
|
||||
filename,
|
||||
data,
|
||||
|
@ -49,17 +49,17 @@ impl<'a> ArchiveEntry<'a> {
|
|||
}
|
||||
|
||||
/// Filename of the entry. Max 99 characters.
|
||||
pub fn filename(&self) -> ArrayString<100> {
|
||||
pub const fn filename(&self) -> ArrayString<100> {
|
||||
self.filename
|
||||
}
|
||||
|
||||
/// Data of the file.
|
||||
pub fn data(&self) -> &'a [u8] {
|
||||
pub const fn data(&self) -> &'a [u8] {
|
||||
self.data
|
||||
}
|
||||
|
||||
/// Filesize in bytes.
|
||||
pub fn size(&self) -> usize {
|
||||
pub const fn size(&self) -> usize {
|
||||
self.size
|
||||
}
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ impl<'a> TarArchive<'a> {
|
|||
|
||||
/// Iterates over all entries of the TAR Archive.
|
||||
/// Returns items of type [`ArchiveEntry`].
|
||||
pub fn entries(&self) -> ArchiveIterator {
|
||||
pub const fn entries(&self) -> ArchiveIterator {
|
||||
ArchiveIterator::new(self)
|
||||
}
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ pub struct ArchiveIterator<'a> {
|
|||
}
|
||||
|
||||
impl<'a> ArchiveIterator<'a> {
|
||||
pub fn new(archive: &'a TarArchive<'a>) -> Self {
|
||||
pub const fn new(archive: &'a TarArchive<'a>) -> Self {
|
||||
Self {
|
||||
archive,
|
||||
block_index: 0,
|
||||
|
@ -117,7 +117,7 @@ impl<'a> ArchiveIterator<'a> {
|
|||
}
|
||||
|
||||
/// Returns a pointer to the next Header.
|
||||
fn next_hdr(&self, block_index: usize) -> *const PosixHeader {
|
||||
const fn next_hdr(&self, block_index: usize) -> *const PosixHeader {
|
||||
let hdr_ptr = &self.archive.data[block_index * BLOCKSIZE];
|
||||
let hdr_ptr = hdr_ptr as *const u8;
|
||||
hdr_ptr as *const PosixHeader
|
||||
|
@ -157,6 +157,10 @@ impl<'a> Iterator for ArchiveIterator<'a> {
|
|||
return None;
|
||||
}
|
||||
|
||||
if hdr.name.is_empty() {
|
||||
log::warn!("Found empty file name",);
|
||||
}
|
||||
|
||||
// fetch data of file from next block(s)
|
||||
let block_count = hdr.payload_block_count();
|
||||
let i_begin = self.block_index * BLOCKSIZE;
|
||||
|
|
|
@ -83,7 +83,7 @@ pub struct StaticCString<const N: usize>([u8; N]);
|
|||
#[allow(unused)]
|
||||
impl<const N: usize> StaticCString<N> {
|
||||
/// Constructor.
|
||||
fn new(bytes: [u8; N]) -> Self {
|
||||
const fn new(bytes: [u8; N]) -> Self {
|
||||
Self(bytes)
|
||||
}
|
||||
|
||||
|
@ -93,6 +93,11 @@ impl<const N: usize> StaticCString<N> {
|
|||
self.as_string().len()
|
||||
}
|
||||
|
||||
/// Returns if the string without NULL-byte is empty.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
|
||||
/// Returns a string without null bytes.
|
||||
pub fn as_string(&self) -> ArrayString<N> {
|
||||
let mut string = ArrayString::new();
|
||||
|
@ -114,7 +119,7 @@ impl<const N: usize> Debug for StaticCString<N> {
|
|||
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
|
||||
let mut debug = f.debug_tuple("Name");
|
||||
let str = self.as_string();
|
||||
if str.len() == 0 {
|
||||
if str.is_empty() {
|
||||
debug.field(&"<empty>");
|
||||
} else {
|
||||
debug.field(&str);
|
||||
|
|
|
@ -40,6 +40,11 @@ SOFTWARE.
|
|||
//! archive formats and their limitations.
|
||||
|
||||
#![cfg_attr(not(test), no_std)]
|
||||
#![deny(rustdoc::all)]
|
||||
#![allow(rustdoc::missing_doc_code_examples)]
|
||||
#![deny(clippy::all)]
|
||||
#![deny(clippy::missing_const_for_fn)]
|
||||
#![deny(missing_debug_implementations)]
|
||||
|
||||
#[cfg_attr(test, macro_use)]
|
||||
#[cfg(test)]
|
||||
|
|
Loading…
Reference in New Issue