Skip to content

Commit

Permalink
Merge pull request #167 from Nadrieril/wasm
Browse files Browse the repository at this point in the history
  • Loading branch information
Nadrieril authored May 30, 2020
2 parents aaba9f7 + a9b0923 commit f554164
Show file tree
Hide file tree
Showing 10 changed files with 222 additions and 109 deletions.
22 changes: 22 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,25 @@ jobs:
with:
command: test

test_wasm:
name: Run wasm tests
runs-on: ubuntu-latest
strategy:
matrix:
rust:
- stable
steps:
- name: Checkout branch
uses: actions/checkout@master
with:
submodules: true
- name: Setup Rust toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: ${{ matrix.rust }}
override: true
- name: Install wasm-pack
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
- name: Run tests
run: wasm-pack test serde_dhall --node
180 changes: 136 additions & 44 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ same name as the corresponding test.

#### [Unreleased]

- Support building to wasm

#### [0.5.2] - 2020-04-12

- Fix #162
Expand Down
9 changes: 8 additions & 1 deletion dhall/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,20 @@ once_cell = "1.3.1"
percent-encoding = "2.1.0"
pest = "2.1"
pest_consume = "1.0"
reqwest = { version = "0.10", features = ["blocking"] }
serde = "1.0"
serde_cbor = "0.9.0"
sha2 = "0.8.1"
smallvec = "1.0.0"
url = "2.1"

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
reqwest = { version = "0.10", features = ["blocking"] }

[target.'cfg(target_arch = "wasm32")'.dependencies]
# Disable native tls because hyper doesn't build on wasm
reqwest = { version = "0.10", default-features = false }
blocking = "0.4.3"

[dev-dependencies]
pretty_assertions = "0.6.1"
version-sync = "0.8"
Expand Down
4 changes: 2 additions & 2 deletions dhall/src/semantics/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::path::Path;
use url::Url;

use crate::error::Error;
use crate::semantics::resolve::ImportLocation;
use crate::semantics::resolve::{download_http_text, ImportLocation};
use crate::syntax::binary;
use crate::syntax::parse_expr;
use crate::Parsed;
Expand All @@ -17,7 +17,7 @@ pub fn parse_file(f: &Path) -> Result<Parsed, Error> {
}

pub fn parse_remote(url: Url) -> Result<Parsed, Error> {
let body = reqwest::blocking::get(url.clone()).unwrap().text().unwrap();
let body = download_http_text(url.clone())?;
let expr = parse_expr(&body)?;
let root = ImportLocation::Remote(url);
Ok(Parsed(expr, root))
Expand Down
80 changes: 23 additions & 57 deletions dhall/src/semantics/resolve/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,36 +12,32 @@ use std::env::VarError;
use std::ffi::OsStr;
use std::fs::File;

#[cfg(any(unix, windows))]
const CACHE_ENV_VAR: &str = "XDG_CACHE_HOME";
#[cfg(unix)]
const ALTERNATE_ENV_VAR: &str = "HOME";

const ALTERNATE_CACHE_ENV_VAR: &str = "HOME";
#[cfg(windows)]
const ALTERNATE_ENV_VAR: &str = "LOCALAPPDATA";

fn alternate_env_var_cache_dir(
provider: impl Fn(&str) -> Result<String, VarError>,
) -> Option<PathBuf> {
provider(ALTERNATE_ENV_VAR)
.map(PathBuf::from)
.map(|env_dir| env_dir.join(".cache").join("dhall"))
.ok()
}
const ALTERNATE_CACHE_ENV_VAR: &str = "LOCALAPPDATA";

fn env_var_cache_dir(
provider: impl Fn(&str) -> Result<String, VarError>,
) -> Option<PathBuf> {
provider("XDG_CACHE_HOME")
.map(PathBuf::from)
.map(|cache_home| cache_home.join("dhall"))
.ok()
#[cfg(any(unix, windows))]
fn load_cache_dir(
env_provider: impl Fn(&str) -> Result<String, VarError> + Copy,
) -> Result<PathBuf, CacheError> {
let env_provider = |s| {
env_provider(s)
.map(PathBuf::from)
.map_err(|_| CacheError::MissingConfiguration)
};
let cache_base_path = env_provider(CACHE_ENV_VAR).or_else(|_| {
env_provider(ALTERNATE_CACHE_ENV_VAR).map(|path| path.join(".cache"))
})?;
Ok(cache_base_path.join("dhall"))
}

#[cfg(not(any(unix, windows)))]
fn load_cache_dir(
provider: impl Fn(&str) -> Result<String, VarError> + Copy,
_provider: impl Fn(&str) -> Result<String, VarError> + Copy,
) -> Result<PathBuf, CacheError> {
env_var_cache_dir(provider)
.or_else(|| alternate_env_var_cache_dir(provider))
.ok_or(CacheError::MissingConfiguration)
Err(CacheError::MissingConfiguration)
}

#[derive(Debug, PartialEq)]
Expand Down Expand Up @@ -184,41 +180,11 @@ mod test {
use rand::Rng;
use std::env::temp_dir;

#[cfg(unix)]
#[test]
fn alternate_env_var_cache_dir_should_result_unix_folder_path() {
let actual =
alternate_env_var_cache_dir(|_| Ok("/home/user".to_string()));
assert_eq!(actual, Some(PathBuf::from("/home/user/.cache/dhall")));
}

#[test]
fn alternate_env_var_cache_dir_should_result_none_on_missing_var() {
let actual = alternate_env_var_cache_dir(|_| Err(VarError::NotPresent));
assert_eq!(actual, None);
}

#[test]
fn env_var_cache_dir_should_result_xdg_cache_home() {
let actual = env_var_cache_dir(|_| {
Ok("/home/user/custom/path/for/cache".to_string())
});
assert_eq!(
actual,
Some(PathBuf::from("/home/user/custom/path/for/cache/dhall"))
);
}

#[test]
fn env_var_cache_dir_should_result_none_on_missing_var() {
let actual = env_var_cache_dir(|_| Err(VarError::NotPresent));
assert_eq!(actual, None);
}

#[cfg(any(unix, windows))]
#[test]
fn load_cache_dir_should_result_xdg_cache_first() {
let actual = load_cache_dir(|var| match var {
"XDG_CACHE_HOME" => Ok("/home/user/custom".to_string()),
CACHE_ENV_VAR => Ok("/home/user/custom".to_string()),
_ => Err(VarError::NotPresent),
});
assert_eq!(actual.unwrap(), PathBuf::from("/home/user/custom/dhall"));
Expand All @@ -228,7 +194,7 @@ mod test {
#[test]
fn load_cache_dir_should_result_alternate() {
let actual = load_cache_dir(|var| match var {
ALTERNATE_ENV_VAR => Ok("/home/user".to_string()),
ALTERNATE_CACHE_ENV_VAR => Ok("/home/user".to_string()),
_ => Err(VarError::NotPresent),
});
assert_eq!(actual.unwrap(), PathBuf::from("/home/user/.cache/dhall"));
Expand Down
16 changes: 13 additions & 3 deletions dhall/src/semantics/resolve/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,7 @@ impl ImportLocation {
fn fetch_text(self) -> Result<String, Error> {
Ok(match self {
ImportLocation::Local(path) => std::fs::read_to_string(&path)?,
ImportLocation::Remote(url) => {
reqwest::blocking::get(url).unwrap().text().unwrap()
}
ImportLocation::Remote(url) => download_http_text(url)?,
ImportLocation::Env(var_name) => match env::var(var_name) {
Ok(val) => val,
Err(_) => return Err(ImportError::MissingEnvVar.into()),
Expand Down Expand Up @@ -197,6 +195,18 @@ fn mkexpr(kind: UnspannedExpr) -> Expr {
Expr::new(kind, Span::Artificial)
}

// TODO: error handling
#[cfg(not(target_arch = "wasm32"))]
pub(crate) fn download_http_text(url: Url) -> Result<String, Error> {
Ok(reqwest::blocking::get(url).unwrap().text().unwrap())
}
#[cfg(target_arch = "wasm32")]
pub(crate) fn download_http_text(url: Url) -> Result<String, Error> {
blocking::block_on(async {
Ok(reqwest::get(url).await.unwrap().text().await.unwrap())
})
}

fn make_aslocation_uniontype() -> Expr {
let text_type = mkexpr(ExprKind::Builtin(Builtin::Text));
let mut union = BTreeMap::default();
Expand Down
4 changes: 3 additions & 1 deletion serde_dhall/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ serde = { version = "1.0", features = ["derive"] }
dhall = { version = "= 0.5.2", path = "../dhall" }
dhall_proc_macros = { version = "= 0.5.0", path = "../dhall_proc_macros" }
doc-comment = "0.3"
reqwest = { version = "0.10", features = ["blocking"] }
url = "2.1"

[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
wasm-bindgen-test = "0.2"

[dev-dependencies]
version-sync = "0.8"
2 changes: 1 addition & 1 deletion serde_dhall/tests/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ fn test_de_typed() {
assert_eq!(parse::<f32>("1.0"), 1.0);

assert_eq!(parse::<String>(r#""foo""#), "foo".to_owned());
assert_eq!(parse::<Vec<u64>>("[] : List Natural"), vec![]);
assert_eq!(parse::<Vec<u64>>("[] : List Natural"), <Vec<u64>>::new());
assert_eq!(parse::<Vec<u64>>("[1, 2]"), vec![1, 2]);
assert_eq!(parse::<Option<u64>>("None Natural"), None);
assert_eq!(parse::<Option<u64>>("Some 1"), Some(1));
Expand Down
12 changes: 12 additions & 0 deletions serde_dhall/tests/wasm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#![cfg(target_arch = "wasm32")]
use wasm_bindgen_test::*;

use serde_dhall::{from_str, FromDhall, StaticType};

#[wasm_bindgen_test]
fn test() {
fn parse<T: FromDhall + StaticType>(s: &str) -> T {
from_str(s).static_type_annotation().parse().unwrap()
}
assert_eq!(parse::<Vec<u64>>("[1, 2]"), vec![1, 2]);
}

0 comments on commit f554164

Please sign in to comment.