1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
//! Runtime managed resource borrowing.
//!
//! This library provides a map that can store one of any type, as well as
//! mutable borrows to each type at the same time.
//!
//! **Note:** This implementation is extracted from [`shred`], with the
//! following differences:
//!
//! * Uses [`downcast-rs`] instead of [`mopa`] for downcasting types.
//! * Adds `Debug` and `PartialEq` implementations for borrow types when the
//!   resource type implements those traits.
//! * Returns `None` instead of panicking for `try_borrow*` functions when the
//!   resource is already borrowed.
//!
//! ## Usage
//!
//! Add the following to `Cargo.toml`
//!
//! ```toml
//! resman = "0.5.0"
//! ```
//!
//! In code:
//!
//! ```rust
//! use resman::Resources;
//!
//! #[derive(Debug)]
//! struct A(u32);
//! #[derive(Debug)]
//! struct B(u32);
//!
//! let mut resources = Resources::default();
//!
//! resources.insert(A(1));
//! resources.insert(B(2));
//!
//! // We can validly have two mutable borrows from the `Resources` map!
//! let mut a = resources.borrow_mut::<A>();
//! let mut b = resources.borrow_mut::<B>();
//! a.0 = 2;
//! b.0 = 3;
//!
//! // We need to explicitly drop the A and B borrows, because they are runtime
//! // managed borrows, and rustc doesn't know to drop them before the immutable
//! // borrows after this.
//! drop(a);
//! drop(b);
//!
//! // Multiple immutable borrows to the same resource are valid.
//! let a_0 = resources.borrow::<A>();
//! let _a_1 = resources.borrow::<A>();
//! let b = resources.borrow::<B>();
//!
//! println!("A: {}", a_0.0);
//! println!("B: {}", b.0);
//!
//! // Trying to mutably borrow a resource that is already borrowed (immutably
//! // or mutably) returns `None`.
//! let a_try_borrow_mut = resources.try_borrow_mut::<A>();
//! let exists = if a_try_borrow_mut.is_some() {
//!     "Some(..)"
//! } else {
//!     "None"
//! };
//! println!("a_try_borrow_mut: {}", exists); // prints "None"
//! ```
//!
//! ### Features
//!
//! * `"debug"`:
//!
//!     The `Debug` implementation for `Resources` will use the `Debug`
//!     implementation for the values when printed. This requires that all
//!     `Resources` to also implement `Debug`.
//!
//!     Given the following:
//!
//!     ```rust,ignore
//!     let mut resources = Resources::default();
//!     resources.insert(1u32);
//!     println!("{:?}", resources);
//!     ```
//!
//!     Without `"debug"` feature:
//!
//!     ```rust,ignore
//!     {TypeId { t:12849923012446332737 }: ".."}
//!     ```
//!
//!     With `"debug"` feature:
//!
//!     ```rust,ignore
//!     {TypeId { t: 12849923012446332737}: 1}
//!     ```
//!
//! ## See Also
//!
//! * [`anymap`]: Map of any type, without multiple mutable borrows.
//! * [`shred`]: Contains `Resources` type, plus a task dispatcher.
//!
//! [`anymap`]: https://github.com/chris-morgan/anymap
//! [`downcast-rs`]: https://github.com/marcianx/downcast-rs
//! [`mopa`]: https://github.com/chris-morgan/mopa
//! [`shred`]: https://github.com/amethyst/shred

pub use crate::{
    entry::Entry, r#ref::Ref, ref_mut::RefMut, resource::Resource, resources::Resources,
};

mod entry;
mod r#ref;
mod ref_mut;
mod resource;
mod resources;