use std::cmp::{max, min};
use std::ops::Range;
use embedder_traits::{EmbedderControlId, EmbedderControlResponse, FilePickerRequest};
use ipc_channel::ipc::IpcSender;
use malloc_size_of_derive::MallocSizeOf;
use num_traits::ToPrimitive;
use profile_traits::generic_callback::GenericCallback;
use serde::{Deserialize, Serialize};
use servo_base::generic_channel::GenericSender;
use servo_url::ImmutableOrigin;
use uuid::Uuid;
use crate::blob_url_store::{BlobBuf, BlobURLStoreError};
#[derive(Clone)]
pub enum FileTokenCheck {
NotRequired,
Required(Uuid),
ShouldFail,
}
#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, Serialize)]
pub struct RelativePos {
pub start: i64,
pub end: Option<i64>,
}
impl RelativePos {
pub fn full_range() -> RelativePos {
RelativePos {
start: 0,
end: None,
}
}
pub fn from_opts(start: Option<i64>, end: Option<i64>) -> RelativePos {
RelativePos {
start: start.unwrap_or(0),
end,
}
}
pub fn slice_inner(&self, rel_pos: &RelativePos) -> RelativePos {
RelativePos {
start: self.start + rel_pos.start,
end: match (self.end, rel_pos.end) {
(Some(old_end), Some(rel_end)) => Some(old_end + rel_end),
(old, None) => old,
(None, rel) => rel,
},
}
}
pub fn to_abs_range(&self, size: usize) -> Range<usize> {
let size = size as i64;
let start = {
if self.start < 0 {
max(size + self.start, 0)
} else {
min(self.start, size)
}
};
let end = match self.end {
Some(rel_end) => {
if rel_end < 0 {
max(size + rel_end, 0)
} else {
min(rel_end, size)
}
},
None => size,
};
let span: i64 = max(end - start, 0);
Range {
start: start.to_usize().unwrap(),
end: (start + span).to_usize().unwrap(),
}
}
pub fn to_abs_blob_range(&self, size: usize) -> Range<usize> {
let orig_range = self.to_abs_range(size);
let start = orig_range.start;
let end = usize::min(orig_range.end + 1, size);
Range { start, end }
}
}
#[derive(Debug, Deserialize, Serialize)]
pub enum FileManagerThreadMsg {
SelectFiles(
EmbedderControlId,
FilePickerRequest,
GenericCallback<EmbedderControlResponse>,
),
ReadFile(
IpcSender<FileManagerResult<ReadFileProgress>>,
Uuid,
ImmutableOrigin,
),
PromoteMemory(Uuid, BlobBuf, bool, ImmutableOrigin),
AddSlicedURLEntry(
Uuid,
RelativePos,
GenericSender<Result<Uuid, BlobURLStoreError>>,
ImmutableOrigin,
),
DecRef(
Uuid,
ImmutableOrigin,
GenericSender<Result<(), BlobURLStoreError>>,
),
ActivateBlobURL(
Uuid,
IpcSender<Result<(), BlobURLStoreError>>,
ImmutableOrigin,
),
RevokeBlobURL(
Uuid,
ImmutableOrigin,
GenericSender<Result<(), BlobURLStoreError>>,
),
}
#[derive(Debug, Deserialize, Serialize)]
pub enum ReadFileProgress {
Meta(BlobBuf),
Partial(Vec<u8>),
EOF,
}
pub type FileManagerResult<T> = Result<T, FileManagerThreadError>;
#[derive(Debug, Deserialize, Serialize)]
pub enum FileManagerThreadError {
InvalidSelection,
UserCancelled,
FileSystemError(String),
BlobURLStoreError(BlobURLStoreError),
}