aria2_core/segment/
segment.rs1use crate::error::{Aria2Error, Result};
2use std::ops::Range;
3
4#[derive(Debug, Clone, Copy, PartialEq)]
5pub enum SegmentStatus {
6 Pending,
7 InProgress,
8 Completed,
9 Error,
10}
11
12#[derive(Debug, Clone, Copy, PartialEq)]
13pub struct Segment {
14 index: usize,
15 start: u64,
16 end: u64,
17 completed_length: u64,
18 status: SegmentStatus,
19}
20
21impl Segment {
22 pub fn new(index: usize, start: u64, end: u64) -> Self {
23 Segment {
24 index,
25 start,
26 end,
27 completed_length: 0,
28 status: SegmentStatus::Pending,
29 }
30 }
31
32 pub fn index(&self) -> usize {
33 self.index
34 }
35
36 pub fn start(&self) -> u64 {
37 self.start
38 }
39
40 pub fn end(&self) -> u64 {
41 self.end
42 }
43
44 pub fn length(&self) -> u64 {
45 self.end - self.start
46 }
47
48 pub fn completed_length(&self) -> u64 {
49 self.completed_length
50 }
51
52 pub fn remaining(&self) -> u64 {
53 self.length() - self.completed_length
54 }
55
56 pub fn status(&self) -> SegmentStatus {
57 self.status
58 }
59
60 pub fn is_completed(&self) -> bool {
61 self.status == SegmentStatus::Completed
62 }
63
64 pub fn is_in_progress(&self) -> bool {
65 self.status == SegmentStatus::InProgress
66 }
67
68 pub fn is_pending(&self) -> bool {
69 self.status == SegmentStatus::Pending
70 }
71
72 pub fn range(&self) -> Range<u64> {
73 self.start..self.end
74 }
75
76 pub fn write_data(&mut self, offset: u64, length: u64) -> Result<()> {
77 if offset < self.start || offset + length > self.end {
78 return Err(Aria2Error::DownloadFailed(format!(
79 "数据偏移超出分段范围: {}-{}",
80 offset, self.end
81 )));
82 }
83
84 self.completed_length += length;
85 self.status = SegmentStatus::InProgress;
86
87 if self.completed_length >= self.length() {
88 self.status = SegmentStatus::Completed;
89 }
90
91 Ok(())
92 }
93
94 pub fn set_status(&mut self, status: SegmentStatus) {
95 self.status = status;
96 }
97}