Implement capability HTTP and downloads (#54)
All checks were successful
Native code generation / deterministic (push) Successful in 11m59s
Imaging and meshing gate / native (push) Successful in 3m55s
JPEG 2000 feature / linux (push) Successful in 2m26s
Native Rust workspace compile / compile (push) Successful in 3m58s
Skia feature / linux (push) Successful in 31m44s

This commit is contained in:
2026-08-09 15:44:42 +00:00
parent d298b4f4c4
commit 3032b16e7b
15 changed files with 5833 additions and 668 deletions

View File

@@ -356,6 +356,45 @@ impl CancellationToken {
}
}
/// Registers an executor-neutral callback and removes it when the returned
/// guard is dropped.
#[must_use = "dropping the guard immediately unregisters the callback"]
pub fn register_callback(&self, callback: Arc<dyn Fn() + Send + Sync>) -> Subscription {
if self.is_cancellation_requested() {
callback();
return Subscription::detached();
}
let id = self.0.next_id.fetch_add(1, Ordering::Relaxed);
self.0
.callbacks
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner)
.insert(id, callback);
if self.is_cancellation_requested() {
if let Some(callback) = self
.0
.callbacks
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner)
.remove(&id)
{
callback();
}
return Subscription::detached();
}
let state = Arc::downgrade(&self.0);
Subscription::new(move || {
let Some(state) = state.upgrade() else {
return;
};
state
.callbacks
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner)
.remove(&id);
})
}
fn register(&self, callback: Arc<dyn Fn() + Send + Sync>) -> CancellationRegistration {
if self.is_cancellation_requested() {
callback();
@@ -528,7 +567,31 @@ pub struct DictionaryKeys<TKey, TValue>(pub Vec<TKey>, pub PhantomData<fn(TValue
pub struct DictionaryEntry(pub Object, pub Object);
pub struct RateLimitLease;
/// Result of a mapped rate-limit acquisition.
///
/// Token-bucket leases do not return a token when dropped; the value records
/// whether a token was acquired or the bounded waiting queue was already full.
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct RateLimitLease {
acquired: bool,
}
impl RateLimitLease {
#[must_use]
pub const fn acquired() -> Self {
Self { acquired: true }
}
#[must_use]
pub const fn rejected() -> Self {
Self { acquired: false }
}
#[must_use]
pub const fn is_acquired(self) -> bool {
self.acquired
}
}
struct CancellationSourceState {
token: CancellationToken,
@@ -641,7 +704,160 @@ pub struct Thread;
pub struct Task<T>(pub PhantomData<fn() -> T>);
pub struct TaskCompletionSource<T>(pub PhantomData<fn(T)>);
struct TaskCompletionState<T> {
next_id: AtomicU64,
result: Mutex<Option<Result<T, crate::Error>>>,
waiters: Mutex<BTreeMap<u64, Waker>>,
}
/// Cloneable completion source used by mapped task-returning APIs.
#[derive(Clone)]
pub struct TaskCompletionSource<T>(Arc<TaskCompletionState<T>>);
impl<T> TaskCompletionSource<T> {
#[must_use]
pub fn new() -> Self {
Self(Arc::new(TaskCompletionState {
next_id: AtomicU64::new(1),
result: Mutex::new(None),
waiters: Mutex::new(BTreeMap::new()),
}))
}
/// Completes the task once and wakes every waiter.
#[must_use]
pub fn try_set_result(&self, value: T) -> bool {
self.try_complete(Ok(value))
}
/// Completes the task with a typed failure once.
#[must_use]
pub fn try_set_error(&self, error: crate::Error) -> bool {
self.try_complete(Err(error))
}
/// Completes the task with mapped cancellation once.
#[must_use]
pub fn try_set_cancelled(&self) -> bool {
self.try_set_error(crate::Error::Cancelled)
}
fn try_complete(&self, value: Result<T, crate::Error>) -> bool {
let mut result = self
.0
.result
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
if result.is_some() {
return false;
}
*result = Some(value);
drop(result);
for (_, waiter) in std::mem::take(
&mut *self
.0
.waiters
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner),
) {
waiter.wake();
}
true
}
#[must_use]
pub fn future(&self) -> TaskCompletionFuture<T> {
TaskCompletionFuture {
state: Arc::clone(&self.0),
waiter_id: None,
}
}
#[must_use]
pub fn is_completed(&self) -> bool {
self.0
.result
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner)
.is_some()
}
}
impl<T> Default for TaskCompletionSource<T> {
fn default() -> Self {
Self::new()
}
}
impl<T> fmt::Debug for TaskCompletionSource<T> {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter
.debug_struct("TaskCompletionSource")
.field("completed", &self.is_completed())
.finish_non_exhaustive()
}
}
/// Future associated with a [`TaskCompletionSource`].
pub struct TaskCompletionFuture<T> {
state: Arc<TaskCompletionState<T>>,
waiter_id: Option<u64>,
}
impl<T: Clone> Future for TaskCompletionFuture<T> {
type Output = Result<T, crate::Error>;
fn poll(mut self: Pin<&mut Self>, context: &mut Context<'_>) -> Poll<Self::Output> {
if let Some(result) = self
.state
.result
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner)
.clone()
{
return Poll::Ready(result);
}
let id = self.waiter_id.unwrap_or_else(|| {
let id = self.state.next_id.fetch_add(1, Ordering::Relaxed);
self.waiter_id = Some(id);
id
});
self.state
.waiters
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner)
.insert(id, context.waker().clone());
let ready = self
.state
.result
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner)
.clone();
if let Some(result) = ready {
self.state
.waiters
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner)
.remove(&id);
self.waiter_id = None;
Poll::Ready(result)
} else {
Poll::Pending
}
}
}
impl<T> Drop for TaskCompletionFuture<T> {
fn drop(&mut self) {
if let Some(id) = self.waiter_id {
self.state
.waiters
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner)
.remove(&id);
}
}
}
/// Cloneable clock boundary used by runtime-neutral client code.
#[derive(Clone)]
@@ -741,7 +957,19 @@ pub struct HttpMethod(pub String);
pub struct AuthenticationHeaderValue(pub String);
pub trait IProgress<T>: Send + Sync {}
/// Executor-neutral progress sink used by mapped upload/download APIs.
pub trait IProgress<T>: Send + Sync {
fn report(&self, value: T);
}
impl<T, F> IProgress<T> for F
where
F: Fn(T) + Send + Sync,
{
fn report(&self, value: T) {
self(value);
}
}
pub struct IEnumerator;