pub struct UnitInfo(/* private fields */);
Implementations§
Source§impl UnitInfo
impl UnitInfo
Sourcepub fn is_normal(&self) -> bool
pub fn is_normal(&self) -> bool
Examples found in repository?
examples/enumerate-items.rs (line 26)
23fn describe_item(item: UnitInfo) {
24 let mut description = String::new();
25
26 if item.is_normal() {
27 description.push_str("normal ");
28 } else if item.is_special() {
29 description.push_str("special ");
30 } else if item.is_meta() {
31 description.push_str("meta ");
32 }
33
34 if item.is_dir() {
35 description.push_str("dir");
36 } else if item.is_file() {
37 description.push_str("file");
38 }
39
40 if item.length() % 7 == 0 {
41 description.push_str("🦀");
42 }
43
44 println!(
45 " {} {:8} {:8} {}\t\t{}",
46 item.space(),
47 item.start(),
48 item.length(),
49 description,
50 item.path().unwrap_or(Path::new("")).display()
51 );
52}
More examples
examples/extract.rs (line 30)
25fn extract(
26 root_dir: &Path,
27 file: &mut ChmFile,
28 item: &UnitInfo,
29) -> Result<(), Box<dyn Error>> {
30 if !item.is_file() || !item.is_normal() {
31 // we only care about normal files
32 return Ok(());
33 }
34 let path = match item.path() {
35 Some(p) => p,
36 // if we can't get the path, ignore it and continue
37 None => return Ok(()),
38 };
39
40 let mut dest = root_dir.to_path_buf();
41 // Note: by design, the path for a normal file is absolute (starts with "/")
42 // so when joining it with the root_dir we need to drop the initial "/".
43 dest.extend(path.components().skip(1));
44
45 // make sure the parent directory exists
46 if let Some(parent) = dest.parent() {
47 fs::create_dir_all(parent)?;
48 }
49
50 let mut f = File::create(dest)?;
51 let mut start_offset = 0;
52 // CHMLib doesn't give us a &[u8] with the file contents directly (e.g.
53 // because it may be compressed) so we need to copy chunks to an
54 // intermediate buffer
55 let mut buffer = vec![0; 1 << 16];
56
57 loop {
58 let bytes_read = file.read(item, start_offset, &mut buffer)?;
59 if bytes_read == 0 {
60 // we've reached the end of the file
61 break;
62 } else {
63 // write this chunk to the file and continue
64 start_offset += bytes_read as u64;
65 f.write_all(&buffer)?;
66 }
67 }
68
69 Ok(())
70}
Sourcepub fn is_special(&self) -> bool
pub fn is_special(&self) -> bool
Examples found in repository?
examples/enumerate-items.rs (line 28)
23fn describe_item(item: UnitInfo) {
24 let mut description = String::new();
25
26 if item.is_normal() {
27 description.push_str("normal ");
28 } else if item.is_special() {
29 description.push_str("special ");
30 } else if item.is_meta() {
31 description.push_str("meta ");
32 }
33
34 if item.is_dir() {
35 description.push_str("dir");
36 } else if item.is_file() {
37 description.push_str("file");
38 }
39
40 if item.length() % 7 == 0 {
41 description.push_str("🦀");
42 }
43
44 println!(
45 " {} {:8} {:8} {}\t\t{}",
46 item.space(),
47 item.start(),
48 item.length(),
49 description,
50 item.path().unwrap_or(Path::new("")).display()
51 );
52}
Sourcepub fn is_meta(&self) -> bool
pub fn is_meta(&self) -> bool
Examples found in repository?
examples/enumerate-items.rs (line 30)
23fn describe_item(item: UnitInfo) {
24 let mut description = String::new();
25
26 if item.is_normal() {
27 description.push_str("normal ");
28 } else if item.is_special() {
29 description.push_str("special ");
30 } else if item.is_meta() {
31 description.push_str("meta ");
32 }
33
34 if item.is_dir() {
35 description.push_str("dir");
36 } else if item.is_file() {
37 description.push_str("file");
38 }
39
40 if item.length() % 7 == 0 {
41 description.push_str("🦀");
42 }
43
44 println!(
45 " {} {:8} {:8} {}\t\t{}",
46 item.space(),
47 item.start(),
48 item.length(),
49 description,
50 item.path().unwrap_or(Path::new("")).display()
51 );
52}
Sourcepub fn is_file(&self) -> bool
pub fn is_file(&self) -> bool
Examples found in repository?
examples/enumerate-items.rs (line 36)
23fn describe_item(item: UnitInfo) {
24 let mut description = String::new();
25
26 if item.is_normal() {
27 description.push_str("normal ");
28 } else if item.is_special() {
29 description.push_str("special ");
30 } else if item.is_meta() {
31 description.push_str("meta ");
32 }
33
34 if item.is_dir() {
35 description.push_str("dir");
36 } else if item.is_file() {
37 description.push_str("file");
38 }
39
40 if item.length() % 7 == 0 {
41 description.push_str("🦀");
42 }
43
44 println!(
45 " {} {:8} {:8} {}\t\t{}",
46 item.space(),
47 item.start(),
48 item.length(),
49 description,
50 item.path().unwrap_or(Path::new("")).display()
51 );
52}
More examples
examples/extract.rs (line 30)
25fn extract(
26 root_dir: &Path,
27 file: &mut ChmFile,
28 item: &UnitInfo,
29) -> Result<(), Box<dyn Error>> {
30 if !item.is_file() || !item.is_normal() {
31 // we only care about normal files
32 return Ok(());
33 }
34 let path = match item.path() {
35 Some(p) => p,
36 // if we can't get the path, ignore it and continue
37 None => return Ok(()),
38 };
39
40 let mut dest = root_dir.to_path_buf();
41 // Note: by design, the path for a normal file is absolute (starts with "/")
42 // so when joining it with the root_dir we need to drop the initial "/".
43 dest.extend(path.components().skip(1));
44
45 // make sure the parent directory exists
46 if let Some(parent) = dest.parent() {
47 fs::create_dir_all(parent)?;
48 }
49
50 let mut f = File::create(dest)?;
51 let mut start_offset = 0;
52 // CHMLib doesn't give us a &[u8] with the file contents directly (e.g.
53 // because it may be compressed) so we need to copy chunks to an
54 // intermediate buffer
55 let mut buffer = vec![0; 1 << 16];
56
57 loop {
58 let bytes_read = file.read(item, start_offset, &mut buffer)?;
59 if bytes_read == 0 {
60 // we've reached the end of the file
61 break;
62 } else {
63 // write this chunk to the file and continue
64 start_offset += bytes_read as u64;
65 f.write_all(&buffer)?;
66 }
67 }
68
69 Ok(())
70}
Sourcepub fn is_dir(&self) -> bool
pub fn is_dir(&self) -> bool
Examples found in repository?
examples/enumerate-items.rs (line 34)
23fn describe_item(item: UnitInfo) {
24 let mut description = String::new();
25
26 if item.is_normal() {
27 description.push_str("normal ");
28 } else if item.is_special() {
29 description.push_str("special ");
30 } else if item.is_meta() {
31 description.push_str("meta ");
32 }
33
34 if item.is_dir() {
35 description.push_str("dir");
36 } else if item.is_file() {
37 description.push_str("file");
38 }
39
40 if item.length() % 7 == 0 {
41 description.push_str("🦀");
42 }
43
44 println!(
45 " {} {:8} {:8} {}\t\t{}",
46 item.space(),
47 item.start(),
48 item.length(),
49 description,
50 item.path().unwrap_or(Path::new("")).display()
51 );
52}
Sourcepub fn space(&self) -> c_int
pub fn space(&self) -> c_int
Examples found in repository?
examples/enumerate-items.rs (line 46)
23fn describe_item(item: UnitInfo) {
24 let mut description = String::new();
25
26 if item.is_normal() {
27 description.push_str("normal ");
28 } else if item.is_special() {
29 description.push_str("special ");
30 } else if item.is_meta() {
31 description.push_str("meta ");
32 }
33
34 if item.is_dir() {
35 description.push_str("dir");
36 } else if item.is_file() {
37 description.push_str("file");
38 }
39
40 if item.length() % 7 == 0 {
41 description.push_str("🦀");
42 }
43
44 println!(
45 " {} {:8} {:8} {}\t\t{}",
46 item.space(),
47 item.start(),
48 item.length(),
49 description,
50 item.path().unwrap_or(Path::new("")).display()
51 );
52}
Sourcepub fn start(&self) -> u64
pub fn start(&self) -> u64
The starting position within the underlying file.
Examples found in repository?
examples/enumerate-items.rs (line 47)
23fn describe_item(item: UnitInfo) {
24 let mut description = String::new();
25
26 if item.is_normal() {
27 description.push_str("normal ");
28 } else if item.is_special() {
29 description.push_str("special ");
30 } else if item.is_meta() {
31 description.push_str("meta ");
32 }
33
34 if item.is_dir() {
35 description.push_str("dir");
36 } else if item.is_file() {
37 description.push_str("file");
38 }
39
40 if item.length() % 7 == 0 {
41 description.push_str("🦀");
42 }
43
44 println!(
45 " {} {:8} {:8} {}\t\t{}",
46 item.space(),
47 item.start(),
48 item.length(),
49 description,
50 item.path().unwrap_or(Path::new("")).display()
51 );
52}
Sourcepub fn length(&self) -> u64
pub fn length(&self) -> u64
The number of bytes in this item.
Examples found in repository?
examples/enumerate-items.rs (line 40)
23fn describe_item(item: UnitInfo) {
24 let mut description = String::new();
25
26 if item.is_normal() {
27 description.push_str("normal ");
28 } else if item.is_special() {
29 description.push_str("special ");
30 } else if item.is_meta() {
31 description.push_str("meta ");
32 }
33
34 if item.is_dir() {
35 description.push_str("dir");
36 } else if item.is_file() {
37 description.push_str("file");
38 }
39
40 if item.length() % 7 == 0 {
41 description.push_str("🦀");
42 }
43
44 println!(
45 " {} {:8} {:8} {}\t\t{}",
46 item.space(),
47 item.start(),
48 item.length(),
49 description,
50 item.path().unwrap_or(Path::new("")).display()
51 );
52}
Sourcepub fn path(&self) -> Option<&Path>
pub fn path(&self) -> Option<&Path>
The item’s filename.
§Security
This path is provided by the original CHM file’s author. It is the
caller’s responsibility to handle malicious input (e.g.
/../../../etc/passwd
).
Examples found in repository?
examples/enumerate-items.rs (line 50)
23fn describe_item(item: UnitInfo) {
24 let mut description = String::new();
25
26 if item.is_normal() {
27 description.push_str("normal ");
28 } else if item.is_special() {
29 description.push_str("special ");
30 } else if item.is_meta() {
31 description.push_str("meta ");
32 }
33
34 if item.is_dir() {
35 description.push_str("dir");
36 } else if item.is_file() {
37 description.push_str("file");
38 }
39
40 if item.length() % 7 == 0 {
41 description.push_str("🦀");
42 }
43
44 println!(
45 " {} {:8} {:8} {}\t\t{}",
46 item.space(),
47 item.start(),
48 item.length(),
49 description,
50 item.path().unwrap_or(Path::new("")).display()
51 );
52}
More examples
examples/extract.rs (line 34)
25fn extract(
26 root_dir: &Path,
27 file: &mut ChmFile,
28 item: &UnitInfo,
29) -> Result<(), Box<dyn Error>> {
30 if !item.is_file() || !item.is_normal() {
31 // we only care about normal files
32 return Ok(());
33 }
34 let path = match item.path() {
35 Some(p) => p,
36 // if we can't get the path, ignore it and continue
37 None => return Ok(()),
38 };
39
40 let mut dest = root_dir.to_path_buf();
41 // Note: by design, the path for a normal file is absolute (starts with "/")
42 // so when joining it with the root_dir we need to drop the initial "/".
43 dest.extend(path.components().skip(1));
44
45 // make sure the parent directory exists
46 if let Some(parent) = dest.parent() {
47 fs::create_dir_all(parent)?;
48 }
49
50 let mut f = File::create(dest)?;
51 let mut start_offset = 0;
52 // CHMLib doesn't give us a &[u8] with the file contents directly (e.g.
53 // because it may be compressed) so we need to copy chunks to an
54 // intermediate buffer
55 let mut buffer = vec![0; 1 << 16];
56
57 loop {
58 let bytes_read = file.read(item, start_offset, &mut buffer)?;
59 if bytes_read == 0 {
60 // we've reached the end of the file
61 break;
62 } else {
63 // write this chunk to the file and continue
64 start_offset += bytes_read as u64;
65 f.write_all(&buffer)?;
66 }
67 }
68
69 Ok(())
70}
Trait Implementations§
Auto Trait Implementations§
impl Freeze for UnitInfo
impl RefUnwindSafe for UnitInfo
impl Send for UnitInfo
impl Sync for UnitInfo
impl Unpin for UnitInfo
impl UnwindSafe for UnitInfo
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more