Skip to content
This repository has been archived by the owner on Oct 23, 2022. It is now read-only.

Split Entry into two different enums to remove unnecessary expects #272

Merged
merged 1 commit into from
Jul 31, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 36 additions & 48 deletions http/src/v0/root_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use async_stream::try_stream;
use bytes::Bytes;
use cid::{Cid, Codec};
use futures::stream::TryStream;
use ipfs::unixfs::ll::walk::{self, ContinuedWalk, Walker};
use ipfs::unixfs::ll::walk::{self, ContinuedWalk, Entry, MetadataEntry, Walker};
use ipfs::unixfs::{ll::file::FileReadFailed, TraversalFailed};
use ipfs::Block;
use ipfs::{Ipfs, IpfsTypes};
Expand Down Expand Up @@ -159,75 +159,63 @@ fn walk<Types: IpfsTypes>(

visit = match walker.continue_walk(&data, &mut cache)? {
ContinuedWalk::File(segment, item) => {
let total_size = item.as_entry()
.total_file_size()
.expect("files do have total_size");

if segment.is_first() {
let path = item.as_entry().path();
let metadata = item
.as_entry()
.metadata()
.expect("files must have metadata");

for mut bytes in tar_helper.apply_file(path, metadata, total_size)?.iter_mut() {
if let Some(bytes) = bytes.take() {
yield bytes;
if let Entry::Metadata(MetadataEntry::File(.., p, md, size)) = item.as_entry() {
if segment.is_first() {
for mut bytes in tar_helper.apply_file(p, md, size)?.iter_mut() {
if let Some(bytes) = bytes.take() {
yield bytes;
}
}
}
}

// even if the largest of files can have 256 kB blocks and about the same
// amount of content, try to consume it in small parts not to grow the buffers
// too much.
// even if the largest of files can have 256 kB blocks and about the same
// amount of content, try to consume it in small parts not to grow the buffers
// too much.

let mut n = 0usize;
let slice = segment.as_ref();
let total = slice.len();
let mut n = 0usize;
let slice = segment.as_ref();
let total = slice.len();

while n < total {
let next = tar_helper.buffer_file_contents(&slice[n..]);
n += next.len();
yield next;
}
while n < total {
let next = tar_helper.buffer_file_contents(&slice[n..]);
n += next.len();
yield next;
}

if segment.is_last() {
if let Some(zeroes) = tar_helper.pad(total_size) {
yield zeroes;
if segment.is_last() {
if let Some(zeroes) = tar_helper.pad(size) {
yield zeroes;
}
}
}

item.into_inner()
},
ContinuedWalk::Directory(item) => {

// only first instances of directories will have the metadata
if let Some(metadata) = item.as_entry().metadata() {
let path = item.as_entry().path();

if let Entry::Metadata(metadata_entry) = item.as_entry() {
let metadata = metadata_entry.metadata();
let path = metadata_entry.path();
for mut bytes in tar_helper.apply_directory(path, metadata)?.iter_mut() {
if let Some(bytes) = bytes.take() {
yield bytes;
}
}
}

item.into_inner()
},
ContinuedWalk::Symlink(bytes, item) => {

// converting a symlink is the most tricky part
let path = item.as_entry().path();
let target = std::str::from_utf8(bytes).map_err(|_| GetError::NonUtf8Symlink)?;
let target = Path::new(target);
let metadata = item.as_entry().metadata().expect("symlink must have metadata");

for mut bytes in tar_helper.apply_symlink(path, target, metadata)?.iter_mut() {
if let Some(bytes) = bytes.take() {
yield bytes;
if let Entry::Metadata(metadata_entry) = item.as_entry() {
// converting a symlink is the most tricky part
let path = metadata_entry.path();
let target = std::str::from_utf8(bytes).map_err(|_| GetError::NonUtf8Symlink)?;
let target = Path::new(target);
let metadata = metadata_entry.metadata();

for mut bytes in tar_helper.apply_symlink(path, target, metadata)?.iter_mut() {
if let Some(bytes) = bytes.take() {
yield bytes;
}
}
}

item.into_inner()
},
};
Expand Down
61 changes: 25 additions & 36 deletions unixfs/examples/get.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ fn main() {
}

fn walk(blocks: ShardedBlockStore, start: &Cid) -> Result<(), Error> {
use ipfs_unixfs::walk::{ContinuedWalk, Walker};
use ipfs_unixfs::walk::{ContinuedWalk, Entry, MetadataEntry, Walker};

let mut buf = Vec::new();
let mut cache = None;
Expand All @@ -72,56 +72,45 @@ fn walk(blocks: ShardedBlockStore, start: &Cid) -> Result<(), Error> {
// items.
visit = match walker.continue_walk(&buf, &mut cache)? {
ContinuedWalk::File(segment, item) => {
let entry = item.as_entry();
let total_size = entry.total_file_size().expect("all files have total size");
// metadata is picked up from the root file and carried until the last block
let metadata = entry.metadata().expect("all files have metadata");

if segment.is_first() {
// this is set on the root block, no actual bytes are present for multiblock
// files
if let Entry::Metadata(MetadataEntry::File(.., path, md, size)) = item.as_entry() {
if segment.is_first() {
// this is set on the root block, no actual bytes are present for multiblock
// files
}

if segment.is_last() {
let mode = md.mode().unwrap_or(0o0644) & 0o7777;
let (seconds, _) = md.mtime().unwrap_or((0, 0));
println!("f {:o} {:>12} {:>16} {:?}", mode, seconds, size, path);
}
}

if segment.is_last() {
let path = entry.path();
let mode = metadata.mode().unwrap_or(0o0644) & 0o7777;
let (seconds, _) = metadata.mtime().unwrap_or((0, 0));

println!("f {:o} {:>12} {:>16} {:?}", mode, seconds, total_size, path);
}

// continue the walk
item.into_inner()
}
ContinuedWalk::Directory(item) => {
// presense of metadata can be used to determine if this is the first apperiance of
// a directory by looking at the metadata: sibling hamt shard buckets do not have
// metadata.
if let Some(metadata) = item.as_entry().metadata() {
if let Entry::Metadata(metadata_entry) = item.as_entry() {
let metadata = metadata_entry.metadata();
let path = item.as_entry().path();

let mode = metadata.mode().unwrap_or(0o0755) & 0o7777;
let (seconds, _) = metadata.mtime().unwrap_or((0, 0));

println!("d {:o} {:>12} {:>16} {:?}", mode, seconds, "-", path);
}

item.into_inner()
}
ContinuedWalk::Symlink(bytes, item) => {
let entry = item.as_entry();
let metadata = entry.metadata().expect("symlink must have metadata");

let path = entry.path();
let target = Path::new(std::str::from_utf8(bytes).unwrap());
let mode = metadata.mode().unwrap_or(0o0755) & 0o7777;
let (seconds, _) = metadata.mtime().unwrap_or((0, 0));

println!(
"s {:o} {:>12} {:>16} {:?} -> {:?}",
mode, seconds, "-", path, target
);

if let Entry::Metadata(metadata_entry) = item.as_entry() {
let metadata = metadata_entry.metadata();
let path = metadata_entry.path();
let target = Path::new(std::str::from_utf8(bytes).unwrap());
let mode = metadata.mode().unwrap_or(0o0755) & 0o7777;
let (seconds, _) = metadata.mtime().unwrap_or((0, 0));
println!(
"s {:o} {:>12} {:>16} {:?} -> {:?}",
mode, seconds, "-", path, target
);
}
item.into_inner()
}
};
Expand Down
Loading