btpc_core/create/
piece_length.rs1use crate::{Error, Result};
2
3pub const PIECE_LENGTH_POLICY_ID: &str = "btpc-piece-v1";
5
6#[derive(Clone, Copy, Debug, Eq, PartialEq)]
8pub enum PieceLengthMode {
9 V1,
11 V2,
13 Hybrid,
15}
16
17const PIECE_LENGTH_BANDS: &[(u64, u64)] = &[
18 (16 * 1024 * 1024, 16 * 1024),
19 (32 * 1024 * 1024, 32 * 1024),
20 (64 * 1024 * 1024, 64 * 1024),
21 (128 * 1024 * 1024, 128 * 1024),
22 (256 * 1024 * 1024, 256 * 1024),
23 (512 * 1024 * 1024, 512 * 1024),
24 (1024 * 1024 * 1024, 1024 * 1024),
25 (2 * 1024 * 1024 * 1024, 2 * 1024 * 1024),
26 (4 * 1024 * 1024 * 1024, 4 * 1024 * 1024),
27 (8 * 1024 * 1024 * 1024, 8 * 1024 * 1024),
28 (16 * 1024 * 1024 * 1024, 16 * 1024 * 1024),
29];
30
31#[must_use]
36pub fn automatic_piece_length(total_length: u64) -> u64 {
37 PIECE_LENGTH_BANDS
38 .iter()
39 .find_map(|(maximum, piece_length)| (total_length <= *maximum).then_some(*piece_length))
40 .unwrap_or(16 * 1024 * 1024)
41}
42
43pub fn validate_piece_length(piece_length: u64, mode: PieceLengthMode) -> Result<u64> {
50 let minimum = match mode {
51 PieceLengthMode::V1 => 1024,
52 PieceLengthMode::V2 | PieceLengthMode::Hybrid => 16 * 1024,
53 };
54 if !piece_length.is_power_of_two() || !(minimum..=16 * 1024 * 1024).contains(&piece_length) {
55 return Err(Error::metainfo_field(
56 "piece length",
57 format!(
58 "must be a power of two between {minimum} and {} bytes",
59 16 * 1024 * 1024
60 ),
61 ));
62 }
63 Ok(piece_length)
64}