use fslite_core::ByteRange;
#[derive(Debug, Eq, PartialEq)]
pub enum RangeError {
Malformed,
MultiRangeUnsupported,
Unsatisfiable,
}
pub fn resolve_range(header: &str, logical_size: u64) -> Result<ByteRange, RangeError> {
let spec = header.strip_prefix("bytes=").ok_or(RangeError::Malformed)?;
if spec.contains(',') {
return Err(RangeError::MultiRangeUnsupported);
}
let (start_str, end_str) = spec.split_once('-').ok_or(RangeError::Malformed)?;
if start_str.is_empty() {
let suffix_len: u64 = end_str.parse().map_err(|_| RangeError::Malformed)?;
if suffix_len == 0 {
return Err(RangeError::Malformed);
}
let start = logical_size.saturating_sub(suffix_len);
return Ok(ByteRange::new(start, logical_size));
}
let start: u64 = start_str.parse().map_err(|_| RangeError::Malformed)?;
if start >= logical_size {
return Err(RangeError::Unsatisfiable);
}
let end = if end_str.is_empty() {
logical_size
} else {
let inclusive_end: u64 = end_str.parse().map_err(|_| RangeError::Malformed)?;
if inclusive_end < start {
return Err(RangeError::Malformed);
}
inclusive_end.saturating_add(1).min(logical_size)
};
Ok(ByteRange::new(start, end))
}