Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions ldraw/src/library.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ pub enum FileLocation {
Local,
}

#[async_trait(?Send)]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
pub trait DocumentLoader<T> {
async fn load_document(
&self,
Expand All @@ -36,7 +37,8 @@ pub trait DocumentLoader<T> {
) -> Result<MultipartDocument, ResolutionError>;
}

#[async_trait(?Send)]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
pub trait LibraryLoader {
async fn load_colors(&self) -> Result<ColorCatalog, ResolutionError>;

Expand Down
19 changes: 17 additions & 2 deletions ldraw/src/resolvers/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,21 @@ impl HttpLoader {
}
}

#[async_trait(?Send)]
/// Compile-time check that `HttpLoader::load_ref` and `load_colors` return
/// `Send` futures on non-wasm targets. See the parallel helper in
/// `resolvers::local` for context.
#[cfg(not(target_arch = "wasm32"))]
#[allow(dead_code)]
fn _assert_httploader_futures_are_send(loader: &HttpLoader, colors: &ColorCatalog) {
fn assert_send<F: Send>(_: &F) {}
let f1 = loader.load_ref(PartAlias::from("dummy".to_string()), false, colors);
assert_send(&f1);
let f2 = loader.load_colors();
assert_send(&f2);
}

#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
impl DocumentLoader<String> for HttpLoader {
async fn load_document(
&self,
Expand All @@ -46,7 +60,8 @@ impl DocumentLoader<String> for HttpLoader {
}
}

#[async_trait(?Send)]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
impl LibraryLoader for HttpLoader {
async fn load_colors(&self) -> Result<ColorCatalog, ResolutionError> {
let ldraw_url_base = self.ldraw_url_base.as_ref();
Expand Down
23 changes: 21 additions & 2 deletions ldraw/src/resolvers/local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,25 @@ impl LocalLoader {
}
}

#[async_trait(?Send)]
/// Compile-time check: on non-wasm targets, `LocalLoader::load_ref` and
/// `load_colors` must return `Send` futures so multi-threaded runtimes can
/// `.await` them on a worker thread. If the future is `!Send`, this function
/// fails to compile, which is the entire point.
///
/// The function is never called; its body exists only to be type-checked by
/// the compiler.
#[cfg(not(target_arch = "wasm32"))]
#[allow(dead_code)]
fn _assert_localloader_futures_are_send(loader: &LocalLoader, colors: &ColorCatalog) {
fn assert_send<F: Send>(_: &F) {}
let f1 = loader.load_ref(PartAlias::from("dummy".to_string()), false, colors);
assert_send(&f1);
let f2 = loader.load_colors();
assert_send(&f2);
}

#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
impl DocumentLoader<PathBuf> for LocalLoader {
async fn load_document(
&self,
Expand All @@ -44,7 +62,8 @@ impl DocumentLoader<PathBuf> for LocalLoader {
}
}

#[async_trait(?Send)]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
impl LibraryLoader for LocalLoader {
async fn load_colors(&self) -> Result<ColorCatalog, ResolutionError> {
let ldrawdir = match self.ldrawdir.clone() {
Expand Down
Loading