convex-rust 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +137 -2
- package/dist/cli/bin.d.ts +2 -0
- package/dist/cli/bin.js +200 -0
- package/dist/cli/build.d.ts +146 -0
- package/dist/cli/build.js +902 -0
- package/dist/cli/demangle.d.ts +7 -0
- package/dist/cli/demangle.js +328 -0
- package/dist/cli/diagnostics.d.ts +34 -0
- package/dist/cli/diagnostics.js +296 -0
- package/dist/cli/generate.d.ts +29 -0
- package/dist/cli/generate.js +82 -0
- package/dist/cli/manifest.d.ts +24 -0
- package/dist/cli/manifest.js +75 -0
- package/dist/cli/rustApi.d.ts +78 -0
- package/dist/cli/rustApi.js +609 -0
- package/dist/cli/scaffold.d.ts +22 -0
- package/dist/cli/scaffold.js +114 -0
- package/dist/cli/shim.d.ts +30 -0
- package/dist/cli/shim.js +140 -0
- package/dist/cli/size.d.ts +17 -0
- package/dist/cli/size.js +73 -0
- package/dist/cli/split.d.ts +20 -0
- package/dist/cli/split.js +140 -0
- package/dist/cli/symbols.d.ts +30 -0
- package/dist/cli/symbols.js +133 -0
- package/dist/cli/toolchain.d.ts +53 -0
- package/dist/cli/toolchain.js +167 -0
- package/dist/cli/validators.d.ts +6 -0
- package/dist/cli/validators.js +66 -0
- package/dist/cli/wasisdk.d.ts +82 -0
- package/dist/cli/wasisdk.js +220 -0
- package/dist/cli/wasmHints.d.ts +29 -0
- package/dist/cli/wasmHints.js +172 -0
- package/dist/runtime/base64.d.ts +4 -0
- package/dist/runtime/base64.js +77 -0
- package/dist/runtime/crypto.d.ts +7 -0
- package/dist/runtime/crypto.js +421 -0
- package/dist/runtime/fastjson.d.ts +3 -0
- package/dist/runtime/fastjson.js +170 -0
- package/dist/runtime/host.d.ts +73 -0
- package/dist/runtime/host.js +1230 -0
- package/dist/runtime/http.d.ts +40 -0
- package/dist/runtime/http.js +157 -0
- package/dist/runtime/index.d.ts +2 -0
- package/dist/runtime/index.js +1 -0
- package/dist/runtime/intl.d.ts +5 -0
- package/dist/runtime/intl.js +69 -0
- package/dist/runtime/tmpfs.d.ts +129 -0
- package/dist/runtime/tmpfs.js +624 -0
- package/dist/runtime/wasi.d.ts +33 -0
- package/dist/runtime/wasi.js +216 -0
- package/package.json +57 -4
- package/rust/convex_fn/Cargo.toml +32 -0
- package/rust/convex_fn/LICENSE +201 -0
- package/rust/convex_fn/build.rs +3 -0
- package/rust/convex_fn/src/args.rs +416 -0
- package/rust/convex_fn/src/crypto.rs +237 -0
- package/rust/convex_fn/src/ctx.rs +1044 -0
- package/rust/convex_fn/src/dns.rs +356 -0
- package/rust/convex_fn/src/error.rs +179 -0
- package/rust/convex_fn/src/executor.rs +577 -0
- package/rust/convex_fn/src/fanout.rs +106 -0
- package/rust/convex_fn/src/fs.rs +19 -0
- package/rust/convex_fn/src/function_ref.rs +219 -0
- package/rust/convex_fn/src/http.rs +441 -0
- package/rust/convex_fn/src/intl.rs +75 -0
- package/rust/convex_fn/src/lib.rs +242 -0
- package/rust/convex_fn/src/logging.rs +222 -0
- package/rust/convex_fn/src/native.rs +360 -0
- package/rust/convex_fn/src/net.rs +122 -0
- package/rust/convex_fn/src/sys.rs +178 -0
- package/rust/convex_fn/src/values.rs +121 -0
- package/rust/convex_fn/src/wire.rs +579 -0
- package/rust/convex_fn_macros/Cargo.toml +13 -0
- package/rust/convex_fn_macros/LICENSE +201 -0
- package/rust/convex_fn_macros/src/derive.rs +632 -0
- package/rust/convex_fn_macros/src/lib.rs +338 -0
- package/rust/convex_reqwest/Cargo.toml +69 -0
- package/rust/convex_reqwest/LICENSE +201 -0
- package/rust/convex_reqwest/src/blocking.rs +287 -0
- package/rust/convex_reqwest/src/body.rs +152 -0
- package/rust/convex_reqwest/src/client.rs +359 -0
- package/rust/convex_reqwest/src/config_types.rs +150 -0
- package/rust/convex_reqwest/src/error.rs +241 -0
- package/rust/convex_reqwest/src/into_url.rs +57 -0
- package/rust/convex_reqwest/src/lib.rs +42 -0
- package/rust/convex_reqwest/src/multipart.rs +140 -0
- package/rust/convex_reqwest/src/request.rs +358 -0
- package/rust/convex_reqwest/src/response.rs +310 -0
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
//! A blocking `Client` API, built on `convex_fn::block_on`.
|
|
2
|
+
//!
|
|
3
|
+
//! Works from plain synchronous code and from inside a running action:
|
|
4
|
+
//! `convex_fn::block_on` detects the nested case and drives the host task
|
|
5
|
+
//! directly (submit + blocking `task_poll`) instead of starting a second tokio
|
|
6
|
+
//! runtime. Because the guest is single-threaded, tasks spawned on the tokio
|
|
7
|
+
//! `LocalSet` (and tokio timers) do not progress while a blocking call is in
|
|
8
|
+
//! flight; do not block on something that needs them.
|
|
9
|
+
|
|
10
|
+
use std::{io, time::Duration};
|
|
11
|
+
|
|
12
|
+
use bytes::Bytes;
|
|
13
|
+
use http::{
|
|
14
|
+
header::{HeaderMap, HeaderName, HeaderValue},
|
|
15
|
+
Method, StatusCode, Version,
|
|
16
|
+
};
|
|
17
|
+
use serde::{de::DeserializeOwned, Serialize};
|
|
18
|
+
use url::Url;
|
|
19
|
+
|
|
20
|
+
use crate::{body::Body, error::Result, into_url::IntoUrl, multipart, redirect, Proxy, Request};
|
|
21
|
+
|
|
22
|
+
fn wait<F: std::future::Future>(f: F) -> F::Output {
|
|
23
|
+
convex_fn::block_on(f)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/// Shortcut method to quickly make a blocking `GET` request.
|
|
27
|
+
pub fn get<T: IntoUrl>(url: T) -> Result<Response> {
|
|
28
|
+
Client::new().get(url).send()
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/// A blocking `Client` to make Requests with.
|
|
32
|
+
#[derive(Clone, Debug)]
|
|
33
|
+
pub struct Client {
|
|
34
|
+
inner: crate::Client,
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
impl Default for Client {
|
|
38
|
+
fn default() -> Self {
|
|
39
|
+
Self::new()
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
impl Client {
|
|
44
|
+
pub fn new() -> Client {
|
|
45
|
+
ClientBuilder::new().build().expect("default client")
|
|
46
|
+
}
|
|
47
|
+
pub fn builder() -> ClientBuilder {
|
|
48
|
+
ClientBuilder::new()
|
|
49
|
+
}
|
|
50
|
+
pub fn get<U: IntoUrl>(&self, url: U) -> RequestBuilder {
|
|
51
|
+
self.request(Method::GET, url)
|
|
52
|
+
}
|
|
53
|
+
pub fn post<U: IntoUrl>(&self, url: U) -> RequestBuilder {
|
|
54
|
+
self.request(Method::POST, url)
|
|
55
|
+
}
|
|
56
|
+
pub fn put<U: IntoUrl>(&self, url: U) -> RequestBuilder {
|
|
57
|
+
self.request(Method::PUT, url)
|
|
58
|
+
}
|
|
59
|
+
pub fn patch<U: IntoUrl>(&self, url: U) -> RequestBuilder {
|
|
60
|
+
self.request(Method::PATCH, url)
|
|
61
|
+
}
|
|
62
|
+
pub fn delete<U: IntoUrl>(&self, url: U) -> RequestBuilder {
|
|
63
|
+
self.request(Method::DELETE, url)
|
|
64
|
+
}
|
|
65
|
+
pub fn head<U: IntoUrl>(&self, url: U) -> RequestBuilder {
|
|
66
|
+
self.request(Method::HEAD, url)
|
|
67
|
+
}
|
|
68
|
+
pub fn request<U: IntoUrl>(&self, method: Method, url: U) -> RequestBuilder {
|
|
69
|
+
RequestBuilder {
|
|
70
|
+
inner: self.inner.request(method, url),
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
pub fn execute(&self, request: Request) -> Result<Response> {
|
|
74
|
+
wait(self.inner.execute(request)).map(Response::new)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/// A `ClientBuilder` can be used to create a blocking `Client`.
|
|
79
|
+
#[derive(Debug)]
|
|
80
|
+
pub struct ClientBuilder {
|
|
81
|
+
inner: crate::ClientBuilder,
|
|
82
|
+
timeout: Option<Duration>,
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
impl Default for ClientBuilder {
|
|
86
|
+
fn default() -> Self {
|
|
87
|
+
Self::new()
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
macro_rules! passthrough {
|
|
92
|
+
($($name:ident($($arg:ident: $ty:ty),*);)*) => {
|
|
93
|
+
$(
|
|
94
|
+
pub fn $name(mut self $(, $arg: $ty)*) -> ClientBuilder {
|
|
95
|
+
self.inner = self.inner.$name($($arg),*);
|
|
96
|
+
self
|
|
97
|
+
}
|
|
98
|
+
)*
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
impl ClientBuilder {
|
|
103
|
+
pub fn new() -> ClientBuilder {
|
|
104
|
+
ClientBuilder {
|
|
105
|
+
inner: crate::ClientBuilder::new(),
|
|
106
|
+
// reqwest::blocking defaults to a 30 s timeout.
|
|
107
|
+
timeout: Some(Duration::from_secs(30)),
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
pub fn build(self) -> Result<Client> {
|
|
112
|
+
let b = match self.timeout {
|
|
113
|
+
Some(t) => self.inner.timeout(t),
|
|
114
|
+
None => self.inner,
|
|
115
|
+
};
|
|
116
|
+
Ok(Client { inner: b.build()? })
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/// Enables a request timeout (`None` disables it).
|
|
120
|
+
pub fn timeout<T: Into<Option<Duration>>>(mut self, timeout: T) -> ClientBuilder {
|
|
121
|
+
self.timeout = timeout.into();
|
|
122
|
+
self
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
pub fn user_agent<V>(mut self, value: V) -> ClientBuilder
|
|
126
|
+
where
|
|
127
|
+
HeaderValue: TryFrom<V>,
|
|
128
|
+
<HeaderValue as TryFrom<V>>::Error: Into<http::Error>,
|
|
129
|
+
{
|
|
130
|
+
self.inner = self.inner.user_agent(value);
|
|
131
|
+
self
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
passthrough! {
|
|
135
|
+
default_headers(headers: HeaderMap);
|
|
136
|
+
https_only(enabled: bool);
|
|
137
|
+
redirect(policy: redirect::Policy);
|
|
138
|
+
proxy(proxy: Proxy);
|
|
139
|
+
no_proxy();
|
|
140
|
+
connect_timeout(timeout: Duration);
|
|
141
|
+
pool_max_idle_per_host(max: usize);
|
|
142
|
+
gzip(enable: bool);
|
|
143
|
+
brotli(enable: bool);
|
|
144
|
+
deflate(enable: bool);
|
|
145
|
+
danger_accept_invalid_certs(accept: bool);
|
|
146
|
+
use_native_tls();
|
|
147
|
+
use_rustls_tls();
|
|
148
|
+
http1_only();
|
|
149
|
+
tcp_nodelay(enabled: bool);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/// A builder to construct the properties of a blocking `Request`.
|
|
154
|
+
#[derive(Debug)]
|
|
155
|
+
#[must_use = "RequestBuilder does nothing until you 'send' it"]
|
|
156
|
+
pub struct RequestBuilder {
|
|
157
|
+
inner: crate::RequestBuilder,
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
impl RequestBuilder {
|
|
161
|
+
pub fn header<K, V>(mut self, key: K, value: V) -> RequestBuilder
|
|
162
|
+
where
|
|
163
|
+
HeaderName: TryFrom<K>,
|
|
164
|
+
<HeaderName as TryFrom<K>>::Error: Into<http::Error>,
|
|
165
|
+
HeaderValue: TryFrom<V>,
|
|
166
|
+
<HeaderValue as TryFrom<V>>::Error: Into<http::Error>,
|
|
167
|
+
{
|
|
168
|
+
self.inner = self.inner.header(key, value);
|
|
169
|
+
self
|
|
170
|
+
}
|
|
171
|
+
pub fn headers(mut self, headers: HeaderMap) -> RequestBuilder {
|
|
172
|
+
self.inner = self.inner.headers(headers);
|
|
173
|
+
self
|
|
174
|
+
}
|
|
175
|
+
pub fn basic_auth<U, P>(mut self, username: U, password: Option<P>) -> RequestBuilder
|
|
176
|
+
where
|
|
177
|
+
U: std::fmt::Display,
|
|
178
|
+
P: std::fmt::Display,
|
|
179
|
+
{
|
|
180
|
+
self.inner = self.inner.basic_auth(username, password);
|
|
181
|
+
self
|
|
182
|
+
}
|
|
183
|
+
pub fn bearer_auth<T: std::fmt::Display>(mut self, token: T) -> RequestBuilder {
|
|
184
|
+
self.inner = self.inner.bearer_auth(token);
|
|
185
|
+
self
|
|
186
|
+
}
|
|
187
|
+
pub fn body<T: Into<Body>>(mut self, body: T) -> RequestBuilder {
|
|
188
|
+
self.inner = self.inner.body(body);
|
|
189
|
+
self
|
|
190
|
+
}
|
|
191
|
+
pub fn timeout(mut self, timeout: Duration) -> RequestBuilder {
|
|
192
|
+
self.inner = self.inner.timeout(timeout);
|
|
193
|
+
self
|
|
194
|
+
}
|
|
195
|
+
pub fn multipart(mut self, form: multipart::Form) -> RequestBuilder {
|
|
196
|
+
self.inner = self.inner.multipart(form);
|
|
197
|
+
self
|
|
198
|
+
}
|
|
199
|
+
pub fn query<T: Serialize + ?Sized>(mut self, query: &T) -> RequestBuilder {
|
|
200
|
+
self.inner = self.inner.query(query);
|
|
201
|
+
self
|
|
202
|
+
}
|
|
203
|
+
pub fn form<T: Serialize + ?Sized>(mut self, form: &T) -> RequestBuilder {
|
|
204
|
+
self.inner = self.inner.form(form);
|
|
205
|
+
self
|
|
206
|
+
}
|
|
207
|
+
pub fn json<T: Serialize + ?Sized>(mut self, json: &T) -> RequestBuilder {
|
|
208
|
+
self.inner = self.inner.json(json);
|
|
209
|
+
self
|
|
210
|
+
}
|
|
211
|
+
pub fn build(self) -> Result<Request> {
|
|
212
|
+
self.inner.build()
|
|
213
|
+
}
|
|
214
|
+
pub fn send(self) -> Result<Response> {
|
|
215
|
+
wait(self.inner.send()).map(Response::new)
|
|
216
|
+
}
|
|
217
|
+
pub fn try_clone(&self) -> Option<RequestBuilder> {
|
|
218
|
+
self.inner.try_clone().map(|inner| RequestBuilder { inner })
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/// A blocking `Response`.
|
|
223
|
+
#[derive(Debug)]
|
|
224
|
+
pub struct Response {
|
|
225
|
+
inner: crate::Response,
|
|
226
|
+
pending: Bytes,
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
impl Response {
|
|
230
|
+
fn new(inner: crate::Response) -> Response {
|
|
231
|
+
Response {
|
|
232
|
+
inner,
|
|
233
|
+
pending: Bytes::new(),
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
pub fn status(&self) -> StatusCode {
|
|
237
|
+
self.inner.status()
|
|
238
|
+
}
|
|
239
|
+
pub fn version(&self) -> Version {
|
|
240
|
+
self.inner.version()
|
|
241
|
+
}
|
|
242
|
+
pub fn headers(&self) -> &HeaderMap {
|
|
243
|
+
self.inner.headers()
|
|
244
|
+
}
|
|
245
|
+
pub fn url(&self) -> &Url {
|
|
246
|
+
self.inner.url()
|
|
247
|
+
}
|
|
248
|
+
pub fn content_length(&self) -> Option<u64> {
|
|
249
|
+
self.inner.content_length()
|
|
250
|
+
}
|
|
251
|
+
pub fn text(self) -> Result<String> {
|
|
252
|
+
wait(self.inner.text())
|
|
253
|
+
}
|
|
254
|
+
pub fn json<T: DeserializeOwned>(self) -> Result<T> {
|
|
255
|
+
wait(self.inner.json())
|
|
256
|
+
}
|
|
257
|
+
pub fn bytes(self) -> Result<Bytes> {
|
|
258
|
+
wait(self.inner.bytes())
|
|
259
|
+
}
|
|
260
|
+
pub fn error_for_status(self) -> Result<Self> {
|
|
261
|
+
let pending = self.pending;
|
|
262
|
+
self.inner
|
|
263
|
+
.error_for_status()
|
|
264
|
+
.map(|inner| Response { inner, pending })
|
|
265
|
+
}
|
|
266
|
+
pub fn error_for_status_ref(&self) -> Result<&Self> {
|
|
267
|
+
self.inner.error_for_status_ref().map(|_| self)
|
|
268
|
+
}
|
|
269
|
+
/// Copies the body into `w`; returns the number of bytes copied.
|
|
270
|
+
pub fn copy_to<W: io::Write + ?Sized>(&mut self, w: &mut W) -> Result<u64> {
|
|
271
|
+
io::copy(self, w).map_err(crate::error::Error::body)
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
impl io::Read for Response {
|
|
276
|
+
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
|
277
|
+
if self.pending.is_empty() {
|
|
278
|
+
match wait(self.inner.chunk())? {
|
|
279
|
+
Some(c) => self.pending = c,
|
|
280
|
+
None => return Ok(0),
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
let n = buf.len().min(self.pending.len());
|
|
284
|
+
buf[..n].copy_from_slice(&self.pending.split_to(n));
|
|
285
|
+
Ok(n)
|
|
286
|
+
}
|
|
287
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
use std::{fmt, pin::Pin, sync::Mutex, task::Poll};
|
|
2
|
+
|
|
3
|
+
use bytes::Bytes;
|
|
4
|
+
use futures_core::Stream;
|
|
5
|
+
use futures_util::TryStream;
|
|
6
|
+
|
|
7
|
+
use crate::error::{BoxError, Error};
|
|
8
|
+
|
|
9
|
+
/// An asynchronous request body.
|
|
10
|
+
pub struct Body {
|
|
11
|
+
inner: Inner,
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
type BoxStream = Pin<Box<dyn Stream<Item = Result<Bytes, BoxError>> + Send>>;
|
|
15
|
+
|
|
16
|
+
enum Inner {
|
|
17
|
+
Bytes(Bytes),
|
|
18
|
+
Stream(Mutex<BoxStream>),
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
impl Body {
|
|
22
|
+
/// Returns a reference to the internal data of the `Body`, or `None` for a
|
|
23
|
+
/// streaming body.
|
|
24
|
+
pub fn as_bytes(&self) -> Option<&[u8]> {
|
|
25
|
+
match &self.inner {
|
|
26
|
+
Inner::Bytes(b) => Some(b),
|
|
27
|
+
Inner::Stream(_) => None,
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/// Wraps a futures `Stream` in a box inside `Body`.
|
|
32
|
+
pub fn wrap_stream<S>(stream: S) -> Body
|
|
33
|
+
where
|
|
34
|
+
S: TryStream + Send + 'static,
|
|
35
|
+
S::Error: Into<BoxError>,
|
|
36
|
+
Bytes: From<S::Ok>,
|
|
37
|
+
{
|
|
38
|
+
let mut stream = Box::pin(stream);
|
|
39
|
+
let s = futures_util::stream::poll_fn(move |cx| {
|
|
40
|
+
stream
|
|
41
|
+
.as_mut()
|
|
42
|
+
.try_poll_next(cx)
|
|
43
|
+
.map(|o| o.map(|r| r.map(Bytes::from).map_err(Into::into)))
|
|
44
|
+
});
|
|
45
|
+
Body {
|
|
46
|
+
inner: Inner::Stream(Mutex::new(Box::pin(s))),
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/// Splits into the bytes of an in-memory body or the stream of a streaming one.
|
|
51
|
+
pub(crate) fn into_source(self) -> Result<Bytes, StreamSource> {
|
|
52
|
+
match self.inner {
|
|
53
|
+
Inner::Bytes(b) => Ok(b),
|
|
54
|
+
Inner::Stream(s) => Err(StreamSource(
|
|
55
|
+
s.into_inner().unwrap_or_else(|e| e.into_inner()),
|
|
56
|
+
)),
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
pub(crate) fn try_clone(&self) -> Option<Body> {
|
|
61
|
+
match &self.inner {
|
|
62
|
+
Inner::Bytes(b) => Some(Body::from(b.clone())),
|
|
63
|
+
Inner::Stream(_) => None,
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/// A streaming request body as a `convex_fn` chunk source (a streamed upload).
|
|
69
|
+
pub(crate) struct StreamSource(BoxStream);
|
|
70
|
+
|
|
71
|
+
impl convex_fn::ChunkSource for StreamSource {
|
|
72
|
+
async fn next_chunk(&mut self) -> convex_fn::Result<Option<Vec<u8>>> {
|
|
73
|
+
let next = std::future::poll_fn(|cx| self.0.as_mut().poll_next(cx)).await;
|
|
74
|
+
match next {
|
|
75
|
+
Some(Ok(c)) => Ok(Some(c.to_vec())),
|
|
76
|
+
Some(Err(e)) => Err(convex_fn::Error::msg(e.to_string())),
|
|
77
|
+
None => Ok(None),
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
impl fmt::Debug for Body {
|
|
83
|
+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
84
|
+
let mut d = f.debug_struct("Body");
|
|
85
|
+
match &self.inner {
|
|
86
|
+
Inner::Bytes(b) => d.field("bytes", &b.len()),
|
|
87
|
+
Inner::Stream(_) => d.field("stream", &"..."),
|
|
88
|
+
};
|
|
89
|
+
d.finish()
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
impl Default for Body {
|
|
94
|
+
fn default() -> Body {
|
|
95
|
+
Body::from(Bytes::new())
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
impl From<Bytes> for Body {
|
|
100
|
+
fn from(b: Bytes) -> Body {
|
|
101
|
+
Body {
|
|
102
|
+
inner: Inner::Bytes(b),
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
impl From<Vec<u8>> for Body {
|
|
107
|
+
fn from(v: Vec<u8>) -> Body {
|
|
108
|
+
Bytes::from(v).into()
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
impl From<&'static [u8]> for Body {
|
|
112
|
+
fn from(v: &'static [u8]) -> Body {
|
|
113
|
+
Bytes::from_static(v).into()
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
impl From<String> for Body {
|
|
117
|
+
fn from(v: String) -> Body {
|
|
118
|
+
Bytes::from(v).into()
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
impl From<&'static str> for Body {
|
|
122
|
+
fn from(v: &'static str) -> Body {
|
|
123
|
+
Bytes::from_static(v.as_bytes()).into()
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
impl http_body::Body for Body {
|
|
128
|
+
type Data = Bytes;
|
|
129
|
+
type Error = Error;
|
|
130
|
+
|
|
131
|
+
fn poll_frame(
|
|
132
|
+
self: Pin<&mut Self>,
|
|
133
|
+
cx: &mut std::task::Context<'_>,
|
|
134
|
+
) -> Poll<Option<Result<http_body::Frame<Bytes>, Error>>> {
|
|
135
|
+
let this = self.get_mut();
|
|
136
|
+
match &mut this.inner {
|
|
137
|
+
Inner::Bytes(b) => {
|
|
138
|
+
if b.is_empty() {
|
|
139
|
+
Poll::Ready(None)
|
|
140
|
+
} else {
|
|
141
|
+
Poll::Ready(Some(Ok(http_body::Frame::data(std::mem::take(b)))))
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
Inner::Stream(s) => {
|
|
145
|
+
let s = s.get_mut().unwrap_or_else(|e| e.into_inner());
|
|
146
|
+
s.as_mut()
|
|
147
|
+
.poll_next(cx)
|
|
148
|
+
.map(|o| o.map(|r| r.map(http_body::Frame::data).map_err(Error::body)))
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|