aria2_core/segment/
pieced_segment.rs1use crate::error::{Aria2Error, Result};
2use aria2_protocol::bittorrent::piece::bitfield::Bitfield;
3
4pub struct PiecedSegment {
5 piece_index: usize,
6 piece_length: u64,
7 bitfield: Bitfield,
8}
9
10impl PiecedSegment {
11 pub fn new(piece_index: usize, piece_length: u64, num_blocks: usize) -> Self {
12 PiecedSegment {
13 piece_index,
14 piece_length,
15 bitfield: Bitfield::new(num_blocks),
16 }
17 }
18
19 pub fn piece_index(&self) -> usize {
20 self.piece_index
21 }
22
23 pub fn piece_length(&self) -> u64 {
24 self.piece_length
25 }
26
27 pub fn num_blocks(&self) -> usize {
28 self.bitfield.len()
29 }
30
31 pub fn is_completed(&self) -> bool {
32 self.bitfield.is_all_set()
33 }
34
35 pub fn mark_block_completed(&mut self, block_index: usize) -> Result<()> {
36 self.bitfield.set(block_index).ok_or_else(|| {
37 Aria2Error::DownloadFailed(format!(
38 "Block index out of range: {} >= {}",
39 block_index,
40 self.bitfield.len()
41 ))
42 })
43 }
44
45 pub fn mark_block_incomplete(&mut self, block_index: usize) -> Result<()> {
46 self.bitfield.clear(block_index).ok_or_else(|| {
47 Aria2Error::DownloadFailed(format!(
48 "Block index out of range: {} >= {}",
49 block_index,
50 self.bitfield.len()
51 ))
52 })
53 }
54
55 pub fn is_block_completed(&self, block_index: usize) -> bool {
56 self.bitfield.test(block_index)
57 }
58
59 pub fn get_next_missing_block(&self) -> Option<usize> {
60 self.bitfield.find_first_clear()
61 }
62
63 pub fn get_completed_blocks(&self) -> Vec<usize> {
64 self.bitfield.iter_set().collect()
65 }
66
67 pub fn get_missing_blocks(&self) -> Vec<usize> {
68 self.bitfield.iter_clear().collect()
69 }
70
71 pub fn completed_blocks_count(&self) -> usize {
72 self.bitfield.count_set()
73 }
74
75 pub fn missing_blocks_count(&self) -> usize {
76 self.bitfield.count_clear()
77 }
78
79 pub fn progress(&self) -> f64 {
80 let total = self.bitfield.len();
81 if total == 0 {
82 0.0
83 } else {
84 (self.completed_blocks_count() as f64 / total as f64) * 100.0
85 }
86 }
87}