1 // Copyright (c) 2023 Huawei Device Co., Ltd. 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 use std::future::Future; 15 use std::pin::Pin; 16 use std::task::{Context, Poll}; 17 18 use ylong_http::response::Response; 19 20 use crate::async_impl::HttpBody; 21 use crate::{ErrorKind, HttpClientError, Sleep}; 22 23 pub(crate) struct TimeoutFuture<T> { 24 pub(crate) timeout: Option<Pin<Box<Sleep>>>, 25 pub(crate) future: T, 26 } 27 28 impl<T> Future for TimeoutFuture<T> 29 where 30 T: Future<Output = Result<Response<HttpBody>, HttpClientError>> + Unpin, 31 { 32 type Output = Result<Response<HttpBody>, HttpClientError>; 33 poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>34 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { 35 let this = self.get_mut(); 36 37 if let Some(delay) = this.timeout.as_mut() { 38 if let Poll::Ready(()) = delay.as_mut().poll(cx) { 39 return Poll::Ready(Err(HttpClientError::new_with_message( 40 ErrorKind::Timeout, 41 "Request timeout", 42 ))); 43 } 44 } 45 match Pin::new(&mut this.future).poll(cx) { 46 Poll::Ready(Ok(mut response)) => { 47 response.body_mut().set_sleep(this.timeout.take()); 48 Poll::Ready(Ok(response)) 49 } 50 Poll::Ready(Err(e)) => Poll::Ready(Err(e)), 51 Poll::Pending => Poll::Pending, 52 } 53 } 54 } 55