dynamic_provider/
feature_alloc.rs

1use crate::{Lt, Provide, ProvideRef, Query};
2use alloc::{boxed::Box, rc::Rc, string::String, sync::Arc};
3
4/// Provides values from a [`Box`].
5///
6/// Auto-implemented for [`Provide<L>`][Provide] implementations.
7/// In turn, `Provide<L>` is implemented for the following:
8/// - `Box<dyn ProvideBox<L>>`
9/// - `Box<dyn ProvideBox<L> + Send>`
10/// - `Box<dyn ProvideBox<L> + Send + Sync>`
11pub trait ProvideBox<L: Lt = ()> {
12    /// Requests that the inner provider fulfill the query.
13    ///
14    /// If the request fails, a `Box<dyn ProvideBox<L>>` is returned.
15    fn provide_box<'this>(
16        self: Box<Self>,
17        query: &mut Query<'_, L>,
18    ) -> Option<Box<dyn ProvideBox<L> + 'this>>
19    where
20        Self: 'this;
21    /// Requests that the inner provider fulfill the query.
22    ///
23    /// If the request fails, a `Box<dyn ProvideBox<L> + Send>` is returned.
24    fn provide_box_send<'this>(
25        self: Box<Self>,
26        query: &mut Query<'_, L>,
27    ) -> Option<Box<dyn ProvideBox<L> + 'this + Send>>
28    where
29        Self: 'this + Send;
30    /// Requests that the inner provider fulfill the query.
31    ///
32    /// If the request fails, a `Box<dyn ProvideBox<L> + Send + Sync>` is returned.
33    fn provide_box_send_sync<'this>(
34        self: Box<Self>,
35        query: &mut Query<'_, L>,
36    ) -> Option<Box<dyn ProvideBox<L> + 'this + Send + Sync>>
37    where
38        Self: 'this + Send + Sync;
39}
40
41impl<P: Provide<L>, L: Lt> ProvideBox<L> for P {
42    fn provide_box<'this>(
43        self: Box<Self>,
44        query: &mut Query<'_, L>,
45    ) -> Option<Box<dyn ProvideBox<L> + 'this>>
46    where
47        Self: 'this,
48    {
49        (*self).provide(query).map(|x| Box::new(x) as _)
50    }
51
52    fn provide_box_send<'this>(
53        self: Box<Self>,
54        query: &mut Query<'_, L>,
55    ) -> Option<Box<dyn ProvideBox<L> + 'this + Send>>
56    where
57        Self: 'this + Send,
58    {
59        (*self).provide(query).map(|x| Box::new(x) as _)
60    }
61
62    fn provide_box_send_sync<'this>(
63        self: Box<Self>,
64        query: &mut Query<'_, L>,
65    ) -> Option<Box<dyn ProvideBox<L> + 'this + Send + Sync>>
66    where
67        Self: 'this + Send + Sync,
68    {
69        (*self).provide(query).map(|x| Box::new(x) as _)
70    }
71}
72
73impl<'data, L: Lt + 'data> Provide<L> for Box<dyn ProvideBox<L> + 'data> {
74    fn provide(self, query: &mut Query<'_, L>) -> Option<Self> {
75        self.provide_box(query)
76    }
77}
78
79impl<'data, L: Lt + 'data> Provide<L> for Box<dyn ProvideBox<L> + Send + 'data> {
80    fn provide(self, query: &mut Query<'_, L>) -> Option<Self> {
81        self.provide_box_send(query)
82    }
83}
84
85impl<'data, L: Lt + 'data> Provide<L> for Box<dyn ProvideBox<L> + Send + Sync + 'data> {
86    fn provide(self, query: &mut Query<'_, L>) -> Option<Self> {
87        self.provide_box_send_sync(query)
88    }
89}
90
91impl<P: ?Sized + ProvideRef<LTail>, LTail: Lt> ProvideRef<LTail> for Box<P> {
92    fn provide_ref<'this>(&'this self, query: &mut Query<'_, Lt!['this, ..LTail]>) {
93        P::provide_ref(self, query);
94    }
95
96    fn provide_mut<'this>(&'this mut self, query: &mut Query<'_, Lt!['this, ..LTail]>) {
97        P::provide_mut(self, query);
98    }
99}
100
101impl<P: ?Sized + ProvideRef<LTail>, LTail: Lt> ProvideRef<LTail> for Rc<P> {
102    fn provide_ref<'this>(&'this self, query: &mut Query<'_, Lt!['this, ..LTail]>) {
103        P::provide_ref(self, query);
104    }
105
106    fn provide_mut<'this>(&'this mut self, query: &mut Query<'_, Lt!['this, ..LTail]>) {
107        if let Some(this) = Rc::get_mut(self) {
108            P::provide_mut(this, query);
109        }
110    }
111}
112
113impl<P: ?Sized + ProvideRef<LTail>, LTail: Lt> ProvideRef<LTail> for Arc<P> {
114    fn provide_ref<'this>(&'this self, query: &mut Query<'_, Lt!['this, ..LTail]>) {
115        P::provide_ref(self, query);
116    }
117
118    fn provide_mut<'this>(&'this mut self, query: &mut Query<'_, Lt!['this, ..LTail]>) {
119        if let Some(this) = Arc::get_mut(self) {
120            P::provide_mut(this, query);
121        }
122    }
123}
124
125impl<L: Lt> Provide<L> for String {
126    fn provide(self, query: &mut Query<L>) -> Option<Self> {
127        query
128            .using(self)
129            .put_value(|this| this)
130            .put_value(|this| this.into_boxed_str())
131            .put_value(|this| this.into_bytes())
132            .put_value(|this| this.into_bytes().into_boxed_slice())
133            .finish()
134    }
135}
136
137impl<LTail: Lt> ProvideRef<LTail> for String {
138    fn provide_ref<'this>(&'this self, query: &mut Query<'_, Lt!['this, ..LTail]>) {
139        str::provide_ref(self, query)
140    }
141}