Skip to main content
Glama
future.rs3.3 kB
use std::{ pin::Pin, task::{ Context, Poll, }, }; use futures::future::BoxFuture; use pin_project_lite::pin_project; use tower::Service; use crate::{ message::{ Message, MessageHead, }, response::Response, }; pin_project! { pub struct ResponseFuture<S, R> where S: Service<Message<R>>, R: MessageHead, { #[pin] pub(crate) inner: S::Future, #[pin] pub(crate) on_success_fut: BoxFuture<'static, ()>, #[pin] pub(crate) on_failure_fut: BoxFuture<'static, ()>, pub(crate) state: State<S::Response, S::Error>, } } #[derive(Clone, Default)] pub(crate) enum State<T, E> { #[default] Initial, Success(Option<T>), Failure(Option<T>), Err(Option<E>), } impl<S, R> Future for ResponseFuture<S, R> where S: Service<Message<R>, Response = Response>, R: MessageHead, { type Output = Result<S::Response, S::Error>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { let mut this = self.project(); loop { match this.state { // Poll the nested service to yield our result State::Initial => { let result = futures::ready!(this.inner.as_mut().poll(cx)); match result { Ok(response) => { if response.status().is_success() { // Transition the state to run the success case *this.state = State::Success(Some(response)); } else { // Transition the state to run the failure case *this.state = State::Failure(Some(response)); } } Err(err) => { // Transition the state to run the failure case *this.state = State::Err(Some(err)); } } } // Poll the on_success future and when ready return the `Ok` type State::Success(sucess_response) => { futures::ready!(this.on_success_fut.poll(cx)); return Poll::Ready(Ok(sucess_response .take() .expect("extracting owned value only happens once"))); } // Poll the on_failure future and when ready return the `Ok` type State::Failure(failure_response) => { futures::ready!(this.on_failure_fut.poll(cx)); return Poll::Ready(Ok(failure_response .take() .expect("extracting owned value only happens once"))); } // Poll the on_failure future and when ready return the `Err` type State::Err(err) => { futures::ready!(this.on_failure_fut.poll(cx)); return Poll::Ready(Err(err .take() .expect("extracting owned value only happens once"))); } } } } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/systeminit/si'

If you have feedback or need assistance with the MCP directory API, please join our Discord server