pict-rs/src/range.rs

69 lines
1.7 KiB
Rust
Raw Normal View History

2021-10-23 04:48:56 +00:00
use crate::{
error::{Error, UploadError},
store::Store,
};
use actix_web::{
2022-03-01 17:23:15 +00:00
http::header::{ByteRangeSpec, ContentRange, ContentRangeSpec, Range},
web::Bytes,
};
2021-10-14 00:06:53 +00:00
use futures_util::stream::{once, Stream};
use std::future::ready;
2022-03-01 17:23:15 +00:00
pub(crate) fn chop_bytes(
byte_range: &ByteRangeSpec,
bytes: Bytes,
length: u64,
) -> Result<impl Stream<Item = Result<Bytes, Error>>, Error> {
if let Some((start, end)) = byte_range.to_satisfiable_range(length) {
2022-03-27 01:46:34 +00:00
// END IS INCLUSIVE
let end = end as usize + 1;
2023-05-08 15:50:11 +00:00
return Ok(once(ready(Ok(bytes.slice(start as usize..end)))));
}
2022-03-01 17:23:15 +00:00
Err(UploadError::Range.into())
}
2022-03-01 17:23:15 +00:00
pub(crate) async fn chop_store<S: Store>(
byte_range: &ByteRangeSpec,
store: &S,
identifier: &S::Identifier,
length: u64,
) -> Result<impl Stream<Item = std::io::Result<Bytes>>, Error>
where
Error: From<S::Error>,
{
if let Some((start, end)) = byte_range.to_satisfiable_range(length) {
2022-03-27 01:46:34 +00:00
// END IS INCLUSIVE
let end = end + 1;
2022-03-01 17:23:15 +00:00
return Ok(store
.to_stream(identifier, Some(start), Some(end.saturating_sub(start)))
.await?);
}
2022-03-01 17:23:15 +00:00
Err(UploadError::Range.into())
}
2022-03-01 17:23:15 +00:00
pub(crate) fn single_bytes_range(range: &Range) -> Option<&ByteRangeSpec> {
if let Range::Bytes(ranges) = range {
if ranges.len() == 1 {
return ranges.get(0);
}
}
2022-03-01 17:23:15 +00:00
None
}
2022-03-01 17:23:15 +00:00
pub(crate) fn to_content_range(
byte_range: &ByteRangeSpec,
instance_length: u64,
) -> Option<ContentRange> {
byte_range
.to_satisfiable_range(instance_length)
.map(|range| {
ContentRange(ContentRangeSpec::Bytes {
range: Some(range),
instance_length: Some(instance_length),
})
})
}