aria2-core 0.2.1

High-performance download engine core: multi-protocol segmented downloads, rate limiting, config management, session persistence, and BitTorrent seeding
Documentation
use crate::error::{Aria2Error, Result};
use aria2_protocol::bittorrent::piece::bitfield::Bitfield;

pub struct PiecedSegment {
    piece_index: usize,
    piece_length: u64,
    bitfield: Bitfield,
}

impl PiecedSegment {
    pub fn new(piece_index: usize, piece_length: u64, num_blocks: usize) -> Self {
        PiecedSegment {
            piece_index,
            piece_length,
            bitfield: Bitfield::new(num_blocks),
        }
    }

    pub fn piece_index(&self) -> usize {
        self.piece_index
    }

    pub fn piece_length(&self) -> u64 {
        self.piece_length
    }

    pub fn num_blocks(&self) -> usize {
        self.bitfield.len()
    }

    pub fn is_completed(&self) -> bool {
        self.bitfield.is_all_set()
    }

    pub fn mark_block_completed(&mut self, block_index: usize) -> Result<()> {
        self.bitfield.set(block_index).ok_or_else(|| {
            Aria2Error::DownloadFailed(format!(
                "Block index out of range: {} >= {}",
                block_index,
                self.bitfield.len()
            ))
        })
    }

    pub fn mark_block_incomplete(&mut self, block_index: usize) -> Result<()> {
        self.bitfield.clear(block_index).ok_or_else(|| {
            Aria2Error::DownloadFailed(format!(
                "Block index out of range: {} >= {}",
                block_index,
                self.bitfield.len()
            ))
        })
    }

    pub fn is_block_completed(&self, block_index: usize) -> bool {
        self.bitfield.test(block_index)
    }

    pub fn get_next_missing_block(&self) -> Option<usize> {
        self.bitfield.find_first_clear()
    }

    pub fn get_completed_blocks(&self) -> Vec<usize> {
        self.bitfield.iter_set().collect()
    }

    pub fn get_missing_blocks(&self) -> Vec<usize> {
        self.bitfield.iter_clear().collect()
    }

    pub fn completed_blocks_count(&self) -> usize {
        self.bitfield.count_set()
    }

    pub fn missing_blocks_count(&self) -> usize {
        self.bitfield.count_clear()
    }

    pub fn progress(&self) -> f64 {
        let total = self.bitfield.len();
        if total == 0 {
            0.0
        } else {
            (self.completed_blocks_count() as f64 / total as f64) * 100.0
        }
    }
}