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
|
[This link](https://www.gnu.org/software/tar/manual/html_section/Formats.html) gives a good overview over possible
|
||||||
archive formats and their limitations.
|
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
|
## Compression
|
||||||
If your tar file is compressed, e.g. bei `gzip`, you need to uncompress the bytes first (e.g. by a *deflate* algorithm),
|
If your tar file is compressed, e.g. bei `.tar.gz`/`gzip`, you need to uncompress the bytes first
|
||||||
before
|
(e.g. by a *gzip* library). Afterwards, this crate can read and write the Tar archive format from the bytes.
|
||||||
|
|
||||||
## MSRV
|
## MSRV
|
||||||
The MSRV is 1.51.0 stable.
|
The MSRV is 1.51.0 stable.
|
||||||
|
@ -30,7 +30,7 @@ use core::fmt::{Debug, Formatter};
|
|||||||
use core::ptr;
|
use core::ptr;
|
||||||
use core::str::FromStr;
|
use core::str::FromStr;
|
||||||
|
|
||||||
/// Describes an entry in a archive.
|
/// Describes an entry in an archive.
|
||||||
/// Currently only supports files but no directories.
|
/// Currently only supports files but no directories.
|
||||||
pub struct ArchiveEntry<'a> {
|
pub struct ArchiveEntry<'a> {
|
||||||
filename: ArrayString<100>,
|
filename: ArrayString<100>,
|
||||||
@ -40,7 +40,7 @@ pub struct ArchiveEntry<'a> {
|
|||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
impl<'a> ArchiveEntry<'a> {
|
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 {
|
ArchiveEntry {
|
||||||
filename,
|
filename,
|
||||||
data,
|
data,
|
||||||
@ -49,17 +49,17 @@ impl<'a> ArchiveEntry<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Filename of the entry. Max 99 characters.
|
/// Filename of the entry. Max 99 characters.
|
||||||
pub fn filename(&self) -> ArrayString<100> {
|
pub const fn filename(&self) -> ArrayString<100> {
|
||||||
self.filename
|
self.filename
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Data of the file.
|
/// Data of the file.
|
||||||
pub fn data(&self) -> &'a [u8] {
|
pub const fn data(&self) -> &'a [u8] {
|
||||||
self.data
|
self.data
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Filesize in bytes.
|
/// Filesize in bytes.
|
||||||
pub fn size(&self) -> usize {
|
pub const fn size(&self) -> usize {
|
||||||
self.size
|
self.size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -95,7 +95,7 @@ impl<'a> TarArchive<'a> {
|
|||||||
|
|
||||||
/// Iterates over all entries of the TAR Archive.
|
/// Iterates over all entries of the TAR Archive.
|
||||||
/// Returns items of type [`ArchiveEntry`].
|
/// Returns items of type [`ArchiveEntry`].
|
||||||
pub fn entries(&self) -> ArchiveIterator {
|
pub const fn entries(&self) -> ArchiveIterator {
|
||||||
ArchiveIterator::new(self)
|
ArchiveIterator::new(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -109,7 +109,7 @@ pub struct ArchiveIterator<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ArchiveIterator<'a> {
|
impl<'a> ArchiveIterator<'a> {
|
||||||
pub fn new(archive: &'a TarArchive<'a>) -> Self {
|
pub const fn new(archive: &'a TarArchive<'a>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
archive,
|
archive,
|
||||||
block_index: 0,
|
block_index: 0,
|
||||||
@ -117,7 +117,7 @@ impl<'a> ArchiveIterator<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a pointer to the next Header.
|
/// 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 = &self.archive.data[block_index * BLOCKSIZE];
|
||||||
let hdr_ptr = hdr_ptr as *const u8;
|
let hdr_ptr = hdr_ptr as *const u8;
|
||||||
hdr_ptr as *const PosixHeader
|
hdr_ptr as *const PosixHeader
|
||||||
@ -157,6 +157,10 @@ impl<'a> Iterator for ArchiveIterator<'a> {
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if hdr.name.is_empty() {
|
||||||
|
log::warn!("Found empty file name",);
|
||||||
|
}
|
||||||
|
|
||||||
// fetch data of file from next block(s)
|
// fetch data of file from next block(s)
|
||||||
let block_count = hdr.payload_block_count();
|
let block_count = hdr.payload_block_count();
|
||||||
let i_begin = self.block_index * BLOCKSIZE;
|
let i_begin = self.block_index * BLOCKSIZE;
|
||||||
|
@ -83,7 +83,7 @@ pub struct StaticCString<const N: usize>([u8; N]);
|
|||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
impl<const N: usize> StaticCString<N> {
|
impl<const N: usize> StaticCString<N> {
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
fn new(bytes: [u8; N]) -> Self {
|
const fn new(bytes: [u8; N]) -> Self {
|
||||||
Self(bytes)
|
Self(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,6 +93,11 @@ impl<const N: usize> StaticCString<N> {
|
|||||||
self.as_string().len()
|
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.
|
/// Returns a string without null bytes.
|
||||||
pub fn as_string(&self) -> ArrayString<N> {
|
pub fn as_string(&self) -> ArrayString<N> {
|
||||||
let mut string = ArrayString::new();
|
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 {
|
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
|
||||||
let mut debug = f.debug_tuple("Name");
|
let mut debug = f.debug_tuple("Name");
|
||||||
let str = self.as_string();
|
let str = self.as_string();
|
||||||
if str.len() == 0 {
|
if str.is_empty() {
|
||||||
debug.field(&"<empty>");
|
debug.field(&"<empty>");
|
||||||
} else {
|
} else {
|
||||||
debug.field(&str);
|
debug.field(&str);
|
||||||
|
@ -40,6 +40,11 @@ SOFTWARE.
|
|||||||
//! archive formats and their limitations.
|
//! archive formats and their limitations.
|
||||||
|
|
||||||
#![cfg_attr(not(test), no_std)]
|
#![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_attr(test, macro_use)]
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
Loading…
Reference in New Issue
Block a user