maybe-sync 0.1.1

Helper crate for libraries that want to have a switch between multi- and single-threaded versions
Documentation
# maybe-sync


This crates helps creating flexible libraries that may work in either
multithreaded and singlethreaded environments.

[![crates](https://img.shields.io/crates/v/maybe-sync.svg?label=maybe-sync)](https://crates.io/crates/maybe-sync)
[![docs](https://docs.rs/maybe-sync/badge.svg)](https://docs.rs/maybe-sync)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE-MIT)
[![License](https://img.shields.io/badge/license-APACHE-blue.svg)](LICENSE-APACHE)

## Why it exists?

Creating library that works in either desktop/server or web-browser environment
could be tough.

In desktop/server environments crates tend to be usable with multiple threads
and add [`Send`] and [`Sync`] trait bounds where needed.
In the same time [`web-sys`] - a de facto standard crate to use browser API -
provides programmer with `!Send + !Sync` types that cannot be used when [`Send`]
or [`Sync`] bounds are placed on the API calls.

For example asset loading crate [`goods`] uses generic executors to drive
loading process.
Some executors work with sendable futures only: [`tokio`],
some requre sendable future to run them on multiple threads:
[`async-std`], [`actix-rt`],
Others work with any futures in single thread: [`wasm_bindgen_futures::spawn_local`]

In [`goods`] one of the basic data sources for web - [`FetchSource`] - uses
browser's Fetch API to retreive data from web and produces non-sendable future.

That's why [`goods::Spawn::spawn`] takes [`maybe_sync::BoxFuture`] that is
a sendable boxed future when "sync" feature is enabled,
allowing using multithreaded future executors.
And without "sync" feature [`maybe_sync::BoxFuture`] is
a non-sendable boxed future and only then [`FetchSource`] exists.

Similar story with ECS crates.
Most of them require that components are [`Send`] + [`Sync`]
so systems can access them from any thread.
This makes it impossible to have types from [`web-sys`] in components.

Some small application may desire to turn off "sync" feature in their
dependencies as they are singlethreaded and would rather not pay for what
they don't use.

## [`MaybeSend`] and [`MaybeSync`]

Marker traits [`MaybeSend`] and [`MaybeSync`] can be used in place of
[`Send`] and [`Sync`] traits in where clauses and bounds.

When "sync" feature is enabled then [`MaybeSend`] is actually reexported [`Send`]
and [`MaybeSync`] is reexported [`Sync`] trait.
Thus allowing types with those bounds to be sent or shared across threads.

When "sync" feature is not enabled then [`MaybeSend`] and [`MaybeSync`] are empty
traits implemented for all types and when used as bounds permit types that
does not satisfy [`Send`] or [`Sync`] bounds.

This makes it impossible to forget enable "sync" feature and accidentally send
`!Send` value to another thread.
Function that uncodintionally send value to another thread
should not use [`MaybeSend`] bound, but an actual [`Send`].

## BoxFuture

Type alias for boxed future. Sendable if "sync" feature is enabled.
It is designed to be used as return type from trait functions
where trait implementations that produce non-sendable futures
exist only when "sync" feature is not enabled.
It can be used as function argument type when [`MaybeSend`] bound is placed.

## Rc

Type alias to [`alloc::rc::Rc`] when "sync" feature is not enabled, or
[`alloc::sync::Arc`] when "sync" feature is enabled. Serves for optimization
purposes for crates that already use [`maybe-sync`] crate.

## Mutex

Type alias to [`parking_lot::Mutex`] when "sync" feature is enabled, or
thin wrapper arond [`core::cell::RefCell`] otherwise. Serves for optimization
purposes for crates that already use [`maybe-sync`] crate.

[`Send`]: https://doc.rust-lang.org/std/marker/trait.Send.html
[`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
[`web-sys`]: https://docs.rs/web-sys
[`goods`]: https://docs.rs/goods
[`tokio`]: https://docs.rs/tokio
[`async-std`]: https://docs.rs/async-std
[`actix-rt`]: https://docs.rs/actix-rt
[`FetchSource`]: https://docs.rs/goods/0.5/wasm32-unknown-unknown/goods/struct.FetchSource.html
[`wasm_bindgen_futures::spawn_local`]: https://docs.rs/wasm-bindgen-futures/0.4/wasm_bindgen_futures/fn.spawn_local.html
[`goods::Spawn::spawn`]: https://docs.rs/goods/0.5/goods/trait.Spawn.html#tymethod.spawn
[`maybe-sync::BoxFuture`]: ./type.BoxFuture.html
[`MaybeSend`]: ./trait.MaybeSend.html
[`MaybeSync`]: ./trait.MaybeSync.html
[`alloc::rc::Rc`]: https://doc.rust-lang.org/alloc/rc/struct.Rc.html
[`alloc::sync::Arc`]: https://doc.rust-lang.org/alloc/sync/struct.Arc.html
[`maybe-sync`]: ./index.html
[`parking_lot::Mutex`]: https://docs.rs/parking_lot/0.10/parking_lot/type.Mutex.html
[`core::cell::RefCell`]: https://doc.rust-lang.org/core/cell/struct.RefCell.html

## License


This repository is licensed under either of

* Apache License, Version 2.0, ([LICENSE-APACHE]LICENSE-APACHE or
  http://www.apache.org/licenses/LICENSE-2.0)
* MIT license ([LICENSE-MIT]LICENSE-MIT or http://opensource.org/licenses/MIT)

at your option.

### Contribution Licensing


Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license,
shall be dual licensed as above, without any additional terms or conditions.