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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
//! Main provide API.
//!
//! The initial design for a provide pattern was proposed in [RFC 3192](https://rust-lang.github.io/rfcs/3192-dyno.html).
//! It was proposed to provide [`Error`](core::error::Error) and API to expose extra context
//! information for errors. While the original RFC was a API general, the current implementation in
//! `core`/`std` is specifically for `Error`. The original proof of concept implementation can be
//! found at <https://github.com/nrc/provide-any>.
//!
//! [`supply`](crate) is a reimagining of the provide API to be more flexable and general purpose.
//! The motivation section of RFC 3192 states the problem this API is trying to solve very well.
//!
//! > However, in practice some kind of partial abstraction is required, where objects are treated
//! > abstractly but can be queried for data only present in a subset of all types which implement
//! > the trait interface. In this case there are only bad options: speculatively downcasting to
//! > concrete types (inefficient, boilerplatey, and fragile due to breaking abstraction) or adding
//! > numerous methods to the trait which might be functionally implemented, typically returning an
//! > Option where None means not applicable for the concrete type (boilerplatey, confusing, and
//! > leads to poor abstractions).
//!
//! <sub> <https://rust-lang.github.io/rfcs/3192-dyno.html#motivation> </sub>
//!
//! A similar pattern that is very useful but rarely seen in the wild is that proposed by
//! [`gdbstub`](https://docs.rs/gdbstub/latest/gdbstub/target/ext/index.html).
//! That of so called Inlineable Dyn Extension Traits (IDETs). You can think of the provide API
//! as an abstract form of this pattern.
//!
//! The core idea of the provide pattern is to use an output parameter to receive a type erased value.
//!
//! You may ask why just returning a type erased value is an issue, and its a good question. The
//! answer is that returning ownership directly requires something like a [`Box`]. However, we
//! don't always have access to a box or don't want the extra allocation. But wait what if we just
//! returned a `&dyn Any`? This doesn't need a box. However, this prevents returning owned values.
//! We are limited to things that can be borrowed from the source.
//!
//! Instead we take another approach. We construct a "hole". A place a value should go. We then
//! give a borrow of this hole to a value for it to "fill".
//!
//! This design has some major advantages.
//! For one it solves the returning ownership issue. Instead the provider transfers ownership into
//! the existing hole we gave it. Because as the requester we know the type of data we want we can
//! use some stack space to store the hole and eventual value.
//! Additionally, this design allows a requester to change the behavior of the hole. For example
//! we can have many holes that all need to be filled by the provider in one operation.
//!
//! Another aspect that `supply` expands on over the RFC is the use of arbitrary length lifetime
//! lists. We won't get into those here. See the [`lt_list`](crate::lt_list) module for more information about
//! those.
//!
//! Connecting this theoretical design to `supply`'s implementation we get the following.
//! The hole is represented by something implementing the [`Want`] trait. This trait has methods
//! for providing it a value to store. The provider then implements [`Provider`] and when it's
//! methods are called provides any values it can to the passed in want.
//!
//! A requester uses a provider by first constructing an empty [`Want`] implementer. Then, the
//! requester calls `.provide()` on the [`Provider`] to give the want a value. Then the requester
//! can remove the value from the want and use it however it needs to. This sequence is automated
//! by the [`request`](crate::request) module. Using [`ProviderExt`] we can use a simple method
//! call of the form `provider.request::<Request>()` to request values from a provider.
use crate;
use crateRequest;
use crate;
use crateWant;
/// Helper for using [`Provider`] as a trait object.
///
/// Normally using [`Provider`] as a trait object would require
/// always naming the lifetime associated type with `Lifetimes = ...`.
/// This helper makes it just a generic.
/// Provider of values.
///
/// Provided values may contain lifetimes from `L` and the `'r` lifetime.
;