summaryrefslogtreecommitdiff
path: root/cli/file_fetcher.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/file_fetcher.rs')
-rw-r--r--cli/file_fetcher.rs72
1 files changed, 39 insertions, 33 deletions
diff --git a/cli/file_fetcher.rs b/cli/file_fetcher.rs
index be3b1a196..4bf6abd93 100644
--- a/cli/file_fetcher.rs
+++ b/cli/file_fetcher.rs
@@ -12,13 +12,16 @@ use crate::tokio_util;
use deno::ErrBox;
use deno::ModuleSpecifier;
use futures::future::Either;
-use futures::Future;
+use futures::future::FutureExt;
+use futures::future::TryFutureExt;
use serde_json;
use std;
use std::collections::HashMap;
use std::fs;
+use std::future::Future;
use std::path::Path;
use std::path::PathBuf;
+use std::pin::Pin;
use std::result::Result;
use std::str;
use std::sync::Arc;
@@ -39,7 +42,7 @@ pub struct SourceFile {
}
pub type SourceFileFuture =
- dyn Future<Item = SourceFile, Error = ErrBox> + Send;
+ dyn Future<Output = Result<SourceFile, ErrBox>> + Send;
/// Simple struct implementing in-process caching to prevent multiple
/// fs reads/net fetches for same file.
@@ -119,14 +122,14 @@ impl SourceFileFetcher {
pub fn fetch_source_file_async(
self: &Self,
specifier: &ModuleSpecifier,
- ) -> Box<SourceFileFuture> {
+ ) -> Pin<Box<SourceFileFuture>> {
let module_url = specifier.as_url().to_owned();
debug!("fetch_source_file. specifier {} ", &module_url);
// Check if this file was already fetched and can be retrieved from in-process cache.
if let Some(source_file) = self.source_file_cache.get(specifier.to_string())
{
- return Box::new(futures::future::ok(source_file));
+ return futures::future::ok(source_file).boxed();
}
let source_file_cache = self.source_file_cache.clone();
@@ -139,7 +142,7 @@ impl SourceFileFetcher {
self.no_remote_fetch,
)
.then(move |result| {
- let mut out = result.map_err(|err| {
+ let mut out = match result.map_err(|err| {
if err.kind() == ErrorKind::NotFound {
// For NotFound, change the message to something better.
DenoError::new(
@@ -150,7 +153,10 @@ impl SourceFileFetcher {
} else {
err
}
- })?;
+ }) {
+ Ok(v) => v,
+ Err(e) => return futures::future::err(e),
+ };
// TODO: move somewhere?
if out.source_code.starts_with(b"#!") {
@@ -160,10 +166,10 @@ impl SourceFileFetcher {
// Cache in-process for subsequent access.
source_file_cache.set(specifier_.to_string(), out.clone());
- Ok(out)
+ futures::future::ok(out)
});
- Box::new(fut)
+ fut.boxed()
}
/// This is main method that is responsible for fetching local or remote files.
@@ -180,29 +186,29 @@ impl SourceFileFetcher {
module_url: &Url,
use_disk_cache: bool,
no_remote_fetch: bool,
- ) -> impl Future<Item = SourceFile, Error = ErrBox> {
+ ) -> impl Future<Output = Result<SourceFile, ErrBox>> {
let url_scheme = module_url.scheme();
let is_local_file = url_scheme == "file";
if let Err(err) = SourceFileFetcher::check_if_supported_scheme(&module_url)
{
- return Either::A(futures::future::err(err));
+ return Either::Left(futures::future::err(err));
}
// Local files are always fetched from disk bypassing cache entirely.
if is_local_file {
match self.fetch_local_file(&module_url) {
Ok(source_file) => {
- return Either::A(futures::future::ok(source_file));
+ return Either::Left(futures::future::ok(source_file));
}
Err(err) => {
- return Either::A(futures::future::err(err));
+ return Either::Left(futures::future::err(err));
}
}
}
// Fetch remote file and cache on-disk for subsequent access
- Either::B(self.fetch_remote_source_async(
+ Either::Right(self.fetch_remote_source_async(
&module_url,
use_disk_cache,
no_remote_fetch,
@@ -306,9 +312,9 @@ impl SourceFileFetcher {
use_disk_cache: bool,
no_remote_fetch: bool,
redirect_limit: i64,
- ) -> Box<SourceFileFuture> {
+ ) -> Pin<Box<SourceFileFuture>> {
if redirect_limit < 0 {
- return Box::new(futures::future::err(too_many_redirects()));
+ return futures::future::err(too_many_redirects()).boxed();
}
let is_blacklisted =
@@ -317,13 +323,13 @@ impl SourceFileFetcher {
if use_disk_cache && !is_blacklisted {
match self.fetch_cached_remote_source(&module_url) {
Ok(Some(source_file)) => {
- return Box::new(futures::future::ok(source_file));
+ return futures::future::ok(source_file).boxed();
}
Ok(None) => {
// there's no cached version
}
Err(err) => {
- return Box::new(futures::future::err(err));
+ return futures::future::err(err).boxed();
}
}
}
@@ -331,7 +337,7 @@ impl SourceFileFetcher {
// If file wasn't found in cache check if we can fetch it
if no_remote_fetch {
// We can't fetch remote file - bail out
- return Box::new(futures::future::err(
+ return futures::future::err(
std::io::Error::new(
std::io::ErrorKind::NotFound,
format!(
@@ -340,7 +346,8 @@ impl SourceFileFetcher {
),
)
.into(),
- ));
+ )
+ .boxed();
}
let download_job = self.progress.add("Download", &module_url.to_string());
@@ -364,7 +371,7 @@ impl SourceFileFetcher {
drop(download_job);
// Recurse
- Either::A(dir.fetch_remote_source_async(
+ Either::Left(dir.fetch_remote_source_async(
&new_module_url,
use_disk_cache,
no_remote_fetch,
@@ -403,12 +410,12 @@ impl SourceFileFetcher {
// Explicit drop to keep reference alive until future completes.
drop(download_job);
- Either::B(futures::future::ok(source_file))
+ Either::Right(futures::future::ok(source_file))
}
}
});
- Box::new(f)
+ f.boxed()
}
/// Get header metadata associated with a remote file.
@@ -891,7 +898,7 @@ mod tests {
// Now the old .headers.json file should have gone! Resolved back to TypeScript
assert_eq!(&(r4.media_type), &msg::MediaType::TypeScript);
assert!(fs::read_to_string(&headers_file_name_3).is_err());
- Ok(())
+ futures::future::ok(())
});
// http_util::fetch_sync_string requires tokio
@@ -969,7 +976,7 @@ mod tests {
.unwrap(),
"text/javascript"
);
- Ok(())
+ futures::future::ok(())
});
tokio_util::run(fut);
@@ -1072,7 +1079,7 @@ mod tests {
// Examine the meta result.
assert_eq!(mod_meta.url.clone(), target_module_url);
- Ok(())
+ futures::future::ok(())
});
tokio_util::run(fut);
@@ -1139,7 +1146,7 @@ mod tests {
// Examine the meta result.
assert_eq!(mod_meta.url.clone(), target_url);
- Ok(())
+ futures::future::ok(())
});
tokio_util::run(fut);
@@ -1184,9 +1191,8 @@ mod tests {
.get_source_file_async(&redirect_url, true, false)
.map(move |r| (r, file_modified))
})
- .then(move |result| {
+ .then(move |(result, file_modified)| {
assert!(result.is_ok());
- let (_, file_modified) = result.unwrap();
let result = fs::File::open(&target_path_);
assert!(result.is_ok());
let file_2 = result.unwrap();
@@ -1195,7 +1201,7 @@ mod tests {
let file_modified_2 = file_metadata_2.modified().unwrap();
assert_eq!(file_modified, file_modified_2);
- Ok(())
+ futures::future::ok(())
});
tokio_util::run(fut);
@@ -1221,7 +1227,7 @@ mod tests {
assert!(result.is_err());
let err = result.err().unwrap();
assert_eq!(err.kind(), ErrorKind::TooManyRedirects);
- Ok(())
+ futures::future::ok(())
});
tokio_util::run(fut);
@@ -1256,7 +1262,7 @@ mod tests {
})
.then(move |result| {
assert!(result.is_ok());
- Ok(())
+ futures::future::ok(())
});
tokio_util::run(fut);
@@ -1297,7 +1303,7 @@ mod tests {
assert_eq!(r2.source_code, b"export const loaded = true;\n");
// Not MediaType::TypeScript due to .headers.json modification
assert_eq!(&(r2.media_type), &msg::MediaType::JavaScript);
- Ok(())
+ futures::future::ok(())
});
tokio_util::run(fut);
@@ -1340,7 +1346,7 @@ mod tests {
assert_eq!(r2.source_code, "export const loaded = true;\n".as_bytes());
// Not MediaType::TypeScript due to .headers.json modification
assert_eq!(&(r2.media_type), &msg::MediaType::JavaScript);
- Ok(())
+ futures::future::ok(())
});
tokio_util::run(fut);