Skip to content

Commit 1d8c3c6

Browse files
committed
feat(wasi): add wasi crate support
Signed-off-by: Roman Volosatovs <[email protected]>
1 parent 761d36a commit 1d8c3c6

File tree

5 files changed

+134
-0
lines changed

5 files changed

+134
-0
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ jobs:
108108
- name: Check
109109
run: cargo check --target wasm32-unknown-unknown
110110

111+
- name: Test WASI
112+
run: cargo test --features wasi
113+
111114
minimal-versions:
112115
runs-on: ubuntu-latest
113116
steps:

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ std = []
4040
bytes = "1"
4141
fnv = "1.0.5"
4242
itoa = "1"
43+
wasi = { version = "0.13", optional = true }
4344

4445
[dev-dependencies]
4546
quickcheck = "1"

src/header/map.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3872,6 +3872,41 @@ mod as_header_name {
38723872
impl<'a> AsHeaderName for &'a String {}
38733873
}
38743874

3875+
#[cfg(feature = "wasi")]
3876+
impl TryFrom<wasi::http::types::Fields> for HeaderMap {
3877+
type Error = Error;
3878+
3879+
fn try_from(fields: wasi::http::types::Fields) -> Result<Self, Self::Error> {
3880+
let mut headers = HeaderMap::new();
3881+
for (name, value) in fields.entries() {
3882+
let name = HeaderName::try_from(name)?;
3883+
let value = HeaderValue::try_from(value)?;
3884+
match headers.entry(name) {
3885+
Entry::Vacant(entry) => {
3886+
entry.insert(value);
3887+
}
3888+
Entry::Occupied(mut entry) => {
3889+
entry.append(value);
3890+
}
3891+
};
3892+
}
3893+
Ok(headers)
3894+
}
3895+
}
3896+
3897+
#[cfg(feature = "wasi")]
3898+
impl From<HeaderMap> for wasi::http::types::Fields {
3899+
fn from(headers: HeaderMap) -> Self {
3900+
let fields = wasi::http::types::Fields::new();
3901+
for (name, value) in &headers {
3902+
fields
3903+
.append(&name.to_string(), &value.as_bytes().to_vec())
3904+
.expect("failed to append header");
3905+
}
3906+
fields
3907+
}
3908+
}
3909+
38753910
#[test]
38763911
fn test_bounds() {
38773912
fn check_bounds<T: Send + Send>() {}

src/method.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,45 @@ mod extension {
419419
}
420420
}
421421

422+
#[cfg(feature = "wasi")]
423+
impl From<Method> for wasi::http::types::Method {
424+
fn from(method: Method) -> Self {
425+
match method {
426+
Method(Get) => Self::Get,
427+
Method(Head) => Self::Head,
428+
Method(Post) => Self::Post,
429+
Method(Put) => Self::Put,
430+
Method(Delete) => Self::Delete,
431+
Method(Connect) => Self::Connect,
432+
Method(Options) => Self::Options,
433+
Method(Trace) => Self::Trace,
434+
Method(Patch) => Self::Patch,
435+
Method(ExtensionInline(inline)) => Self::Other(inline.as_str().into()),
436+
Method(ExtensionAllocated(allocated)) => Self::Other(allocated.as_str().into()),
437+
}
438+
}
439+
}
440+
441+
#[cfg(feature = "wasi")]
442+
impl TryFrom<wasi::http::types::Method> for Method {
443+
type Error = InvalidMethod;
444+
445+
fn try_from(method: wasi::http::types::Method) -> Result<Self, Self::Error> {
446+
match method {
447+
wasi::http::types::Method::Get => Ok(Self::GET),
448+
wasi::http::types::Method::Head => Ok(Self::HEAD),
449+
wasi::http::types::Method::Post => Ok(Self::POST),
450+
wasi::http::types::Method::Put => Ok(Self::PUT),
451+
wasi::http::types::Method::Delete => Ok(Self::DELETE),
452+
wasi::http::types::Method::Connect => Ok(Self::CONNECT),
453+
wasi::http::types::Method::Options => Ok(Self::OPTIONS),
454+
wasi::http::types::Method::Trace => Ok(Self::TRACE),
455+
wasi::http::types::Method::Patch => Ok(Self::PATCH),
456+
wasi::http::types::Method::Other(method) => method.parse(),
457+
}
458+
}
459+
}
460+
422461
#[cfg(test)]
423462
mod test {
424463
use super::*;
@@ -482,4 +521,18 @@ mod test {
482521
);
483522
}
484523
}
524+
525+
#[cfg(feature = "wasi")]
526+
#[test]
527+
fn test_method_wasi_conv() {
528+
use std::convert::TryInto;
529+
530+
let m: Method = wasi::http::types::Method::Get
531+
.try_into()
532+
.expect("failed to convert WASI method");
533+
assert_eq!(m, Method::GET);
534+
535+
let m: wasi::http::types::Method = Method::GET.into();
536+
assert!(matches!(m, wasi::http::types::Method::Get));
537+
}
485538
}

src/uri/scheme.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,34 @@ impl From<Scheme2> for Scheme {
335335
}
336336
}
337337

338+
#[cfg(feature = "wasi")]
339+
impl From<Scheme> for wasi::http::types::Scheme {
340+
fn from(scheme: Scheme) -> Self {
341+
use self::Protocol::*;
342+
use self::Scheme2::*;
343+
344+
match scheme.inner {
345+
Standard(Http) => Self::Http,
346+
Standard(Https) => Self::Https,
347+
Other(v) => Self::Other(v.to_string()),
348+
None => unreachable!(),
349+
}
350+
}
351+
}
352+
353+
#[cfg(feature = "wasi")]
354+
impl TryFrom<wasi::http::types::Scheme> for Scheme {
355+
type Error = InvalidUri;
356+
357+
fn try_from(scheme: wasi::http::types::Scheme) -> Result<Self, Self::Error> {
358+
match scheme {
359+
wasi::http::types::Scheme::Http => Ok(Self::HTTP),
360+
wasi::http::types::Scheme::Https => Ok(Self::HTTPS),
361+
wasi::http::types::Scheme::Other(scheme) => scheme.parse(),
362+
}
363+
}
364+
}
365+
338366
#[cfg(test)]
339367
mod test {
340368
use super::*;
@@ -358,4 +386,18 @@ mod test {
358386
fn scheme(s: &str) -> Scheme {
359387
s.parse().expect(&format!("Invalid scheme: {}", s))
360388
}
389+
390+
#[cfg(feature = "wasi")]
391+
#[test]
392+
fn wasi_conv() {
393+
use std::convert::TryInto;
394+
395+
let s: Scheme = wasi::http::types::Scheme::Http
396+
.try_into()
397+
.expect("failed to convert WASI scheme");
398+
assert_eq!(s, Scheme::HTTP);
399+
400+
let s: wasi::http::types::Scheme = Scheme::HTTP.into();
401+
assert!(matches!(s, wasi::http::types::Scheme::Http));
402+
}
361403
}

0 commit comments

Comments
 (0)