1use core::marker::PhantomData;
2
3pub use first::FirstArgumentProvided;
4pub use last::LastArgumentProvided;
5pub use ByMut as r#mut;
6pub use ByRef as r#ref;
7pub use Value as value;
8
9pub trait Argument<'a, ImplicitBounds = &'a Self> {
10 type Argument;
11}
12
13pub trait ArgumentType: for<'a> Argument<'a> {
14 fn re_borrow<'a: 'b, 'b>(arg: ArgumentOfType<'a, Self>) -> ArgumentOfType<'b, Self>;
15}
16
17pub trait ProvideArgument {
18 type ProvideArgumentType: ArgumentType;
19
20 fn provide_argument_to<
23 Out,
24 F: for<'arg> FnOnce(ArgumentOfType<'arg, Self::ProvideArgumentType>) -> Out,
25 >(
26 &self,
27 f: F,
28 ) -> Out;
29}
30
31pub struct Value<T>(PhantomData<T>, Invalid);
33pub struct ByRef<T: ?Sized>(PhantomData<T>, Invalid);
35pub struct ByMut<T: ?Sized>(PhantomData<T>, Invalid);
37
38#[derive(Debug, Clone, Copy, PartialEq, Eq)]
39pub struct Copied<T: Copy>(pub(super) T);
40#[derive(Debug, Clone, Copy, PartialEq, Eq)]
41pub struct Cloned<T: Clone>(pub(super) T);
42#[derive(Debug, Clone, Copy, PartialEq, Eq)]
43pub struct Refed<T>(pub(super) T);
44
45#[derive(Debug, Clone, Copy, PartialEq, Eq)]
46pub struct With<Cbk>(pub(super) Cbk);
47
48impl<'a, T> Argument<'a> for Value<T> {
49 type Argument = T;
50}
51
52impl<T> ArgumentType for Value<T> {
53 fn re_borrow<'a: 'b, 'b>(arg: ArgumentOfType<'a, Self>) -> ArgumentOfType<'b, Self> {
54 arg
55 }
56}
57
58impl<'a, T: ?Sized> Argument<'a> for ByRef<T> {
59 type Argument = &'a T;
60}
61
62impl<T: ?Sized> ArgumentType for ByRef<T> {
63 fn re_borrow<'a: 'b, 'b>(arg: ArgumentOfType<'a, Self>) -> ArgumentOfType<'b, Self> {
64 arg
65 }
66}
67
68impl<'a, T: ?Sized> Argument<'a> for ByMut<T> {
69 type Argument = &'a mut T;
70}
71
72impl<T: ?Sized> ArgumentType for ByMut<T> {
73 fn re_borrow<'a: 'b, 'b>(arg: ArgumentOfType<'a, Self>) -> ArgumentOfType<'b, Self> {
74 arg
75 }
76}
77
78impl<T: Copy> ProvideArgument for Copied<T> {
79 type ProvideArgumentType = Value<T>;
80
81 fn provide_argument_to<
86 Out,
87 F: for<'arg> FnOnce(ArgumentOfType<'arg, Self::ProvideArgumentType>) -> Out,
88 >(
89 &self,
90 f: F,
91 ) -> Out {
92 f(self.0)
93 }
94}
95impl<T: Clone> ProvideArgument for Cloned<T> {
96 type ProvideArgumentType = Value<T>;
97
98 fn provide_argument_to<
103 Out,
104 F: for<'arg> FnOnce(ArgumentOfType<'arg, Self::ProvideArgumentType>) -> Out,
105 >(
106 &self,
107 f: F,
108 ) -> Out {
109 f(self.0.clone())
110 }
111}
112
113impl<T> ProvideArgument for Refed<T> {
114 type ProvideArgumentType = ByRef<T>;
115
116 fn provide_argument_to<
121 Out,
122 F: for<'arg> FnOnce(ArgumentOfType<'arg, Self::ProvideArgumentType>) -> Out,
123 >(
124 &self,
125 f: F,
126 ) -> Out {
127 f(&self.0)
128 }
129}
130
131impl<Arg, Cbk: crate::Callable<(), Output = Arg>> ProvideArgument for With<Cbk> {
132 type ProvideArgumentType = Value<Arg>;
133
134 fn provide_argument_to<
135 Out,
136 F: for<'arg> FnOnce(ArgumentOfType<'arg, Self::ProvideArgumentType>) -> Out,
137 >(
138 &self,
139 f: F,
140 ) -> Out {
141 f(self.0.call_fn(()))
142 }
143}
144
145mod last {
146 use super::*;
147
148 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
149 pub struct LastArgumentProvided<
150 F: super::super::CallableWithFixedArguments,
151 A: ProvideArgument<ProvideArgumentType = <F::FixedArgumentTypes as ArgumentTypes>::Last>,
152 > {
153 pub(crate) f: F,
154 pub(crate) last_argument: A,
155 }
156
157 impl<
158 F: super::super::CallableWithFixedArguments,
159 A: ProvideArgument<ProvideArgumentType = <F::FixedArgumentTypes as ArgumentTypes>::Last>,
160 > crate::IsCallable for LastArgumentProvided<F, A>
161 {
162 }
163
164 impl<
166 Out,
167 F: super::super::CallableWithFixedArguments<Output = Out>,
168 A: ProvideArgument<ProvideArgumentType = <F::FixedArgumentTypes as ArgumentTypes>::Last>,
169 >
170 crate::Callable<ArgumentsOfTypes<'_, <F::FixedArgumentTypes as ArgumentTypes>::LastTrimmed>>
171 for LastArgumentProvided<F, A>
172 {
173 type Output = Out;
174
175 fn call_fn(
176 &self,
177 args: ArgumentsOfTypes<'_, <F::FixedArgumentTypes as ArgumentTypes>::LastTrimmed>,
178 ) -> Self::Output {
179 self.last_argument
180 .provide_argument_to(move |last| self.f.call_with_appended_args(args, last))
181 }
182 }
183
184 impl<
185 Out,
186 F: super::super::CallableWithFixedArguments<Output = Out>,
187 A: ProvideArgument<ProvideArgumentType = <F::FixedArgumentTypes as ArgumentTypes>::Last>,
188 > crate::CallableWithFixedArguments for LastArgumentProvided<F, A>
189 {
190 type FixedArgumentTypes = <F::FixedArgumentTypes as ArgumentTypes>::LastTrimmed;
191 }
192}
193
194mod first {
195 use super::*;
196
197 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
198 pub struct FirstArgumentProvided<
199 F: super::super::CallableWithFixedArguments,
200 A: ProvideArgument<ProvideArgumentType = <F::FixedArgumentTypes as ArgumentTypes>::First>,
201 > {
202 pub(crate) f: F,
203 pub(crate) first_argument: A,
204 }
205
206 impl<
207 F: super::super::CallableWithFixedArguments,
208 A: ProvideArgument<ProvideArgumentType = <F::FixedArgumentTypes as ArgumentTypes>::First>,
209 > super::super::IsCallable for FirstArgumentProvided<F, A>
210 {
211 }
212
213 impl<
214 Out,
215 F: super::super::CallableWithFixedArguments<Output = Out>,
216 A: ProvideArgument<ProvideArgumentType = <F::FixedArgumentTypes as ArgumentTypes>::First>,
217 >
218 super::super::Callable<
219 ArgumentsOfTypes<'_, <F::FixedArgumentTypes as ArgumentTypes>::FirstTrimmed>,
220 > for FirstArgumentProvided<F, A>
221 {
222 type Output = Out;
223
224 fn call_fn(
225 &self,
226 args: ArgumentsOfTypes<'_, <F::FixedArgumentTypes as ArgumentTypes>::FirstTrimmed>,
227 ) -> Self::Output {
228 self.first_argument
229 .provide_argument_to(move |first| self.f.call_with_prepended_args(first, args))
230 }
231 }
232
233 impl<
234 Out,
235 F: super::super::CallableWithFixedArguments<Output = Out>,
236 A: ProvideArgument<ProvideArgumentType = <F::FixedArgumentTypes as ArgumentTypes>::First>,
237 > super::super::CallableWithFixedArguments for FirstArgumentProvided<F, A>
238 {
239 type FixedArgumentTypes = <F::FixedArgumentTypes as ArgumentTypes>::FirstTrimmed;
240 }
241}
242
243pub trait Arguments<'a, ImplicitBounds = &'a Self> {
244 type Arguments: super::Tuple;
245}
246
247pub trait PrependArgument<Arg: ArgumentType>: ArgumentTypes {
248 type Prepended: ArgumentTypes<First = Arg, FirstTrimmed = Self>;
249
250 fn prepend_argument<'a>(
251 first: ArgumentOfType<'a, Arg>,
252 args: ArgumentsOfTypes<'a, Self>,
253 ) -> ArgumentsOfTypes<'a, Self::Prepended>;
254}
255
256pub trait AppendArgument<Arg: ArgumentType>: ArgumentTypes {
257 type Appended: ArgumentTypes<Last = Arg, LastTrimmed = Self>;
258
259 fn append_argument<'a>(
260 args: ArgumentsOfTypes<'a, Self>,
261 last: ArgumentOfType<'a, Arg>,
262 ) -> ArgumentsOfTypes<'a, Self::Appended>;
263}
264
265pub trait ArgumentTypes: super::Tuple + for<'a> Arguments<'a> {
266 type First: ArgumentType;
267 type FirstTrimmed: ArgumentTypes + PrependArgument<Self::First, Prepended = Self>;
268
269 type Last: ArgumentType;
270 type LastTrimmed: ArgumentTypes + AppendArgument<Self::Last, Appended = Self>;
271
272 fn re_borrow<'a: 'b, 'b>(args: ArgumentsOfTypes<'a, Self>) -> ArgumentsOfTypes<'b, Self>;
273
274 fn from_prepended<'a>(
275 first: ArgumentOfType<'a, Self::First>,
276 args: ArgumentsOfTypes<'a, Self::FirstTrimmed>,
277 ) -> ArgumentsOfTypes<'a, Self> {
278 <Self::FirstTrimmed as PrependArgument<Self::First>>::prepend_argument(first, args)
279 }
280
281 fn from_appended<'a>(
282 args: ArgumentsOfTypes<'a, Self::LastTrimmed>,
283 last: ArgumentOfType<'a, Self::Last>,
284 ) -> ArgumentsOfTypes<'a, Self> {
285 <Self::LastTrimmed as AppendArgument<Self::Last>>::append_argument(args, last)
286 }
287}
288
289pub type ArgumentOfType<'a, A> = <A as Argument<'a>>::Argument;
290pub type ArgumentsOfTypes<'a, A> = <A as Arguments<'a>>::Arguments;
291
292pub enum Invalid {}
293
294impl<'a> Argument<'a> for Invalid {
295 type Argument = Invalid;
296}
297
298impl ArgumentType for Invalid {
299 fn re_borrow<'a: 'b, 'b>(arg: ArgumentOfType<'a, Self>) -> ArgumentOfType<'b, Self> {
300 match arg {}
301 }
302}
303
304pub enum InvalidTuple {}
305
306impl super::sealed::Sealed for InvalidTuple {}
307impl super::Tuple for InvalidTuple {}
308
309impl<'a> Arguments<'a> for InvalidTuple {
310 type Arguments = InvalidTuple;
311}
312
313impl ArgumentTypes for InvalidTuple {
314 type First = Invalid2;
315 type FirstTrimmed = InvalidTuple;
316 type Last = Invalid2;
317 type LastTrimmed = InvalidTuple;
318
319 fn re_borrow<'a: 'b, 'b>(args: ArgumentsOfTypes<'a, Self>) -> ArgumentsOfTypes<'b, Self> {
320 match args {}
321 }
322}
323
324impl PrependArgument<Invalid> for InvalidTuple {
325 type Prepended = ();
326
327 fn prepend_argument<'a>(
328 first: ArgumentOfType<'a, Invalid>,
329 _: ArgumentsOfTypes<'a, Self>,
330 ) -> ArgumentsOfTypes<'a, Self::Prepended> {
331 match first {}
332 }
333}
334
335impl PrependArgument<Invalid2> for InvalidTuple {
336 type Prepended = InvalidTuple;
337
338 fn prepend_argument<'a>(
339 first: ArgumentOfType<'a, Invalid2>,
340 _: ArgumentsOfTypes<'a, Self>,
341 ) -> ArgumentsOfTypes<'a, Self::Prepended> {
342 match first {}
343 }
344}
345
346impl AppendArgument<Invalid> for InvalidTuple {
347 type Appended = ();
348
349 fn append_argument<'a>(
350 _: ArgumentsOfTypes<'a, Self>,
351 last: ArgumentOfType<'a, Invalid>,
352 ) -> ArgumentsOfTypes<'a, Self::Appended> {
353 match last {}
354 }
355}
356
357impl AppendArgument<Invalid2> for InvalidTuple {
358 type Appended = InvalidTuple;
359
360 fn append_argument<'a>(
361 _: ArgumentsOfTypes<'a, Self>,
362 last: ArgumentOfType<'a, Invalid2>,
363 ) -> ArgumentsOfTypes<'a, Self::Appended> {
364 match last {}
365 }
366}
367
368pub enum Invalid2 {}
369
370impl<'a> Argument<'a> for Invalid2 {
371 type Argument = Invalid2;
372}
373
374impl ArgumentType for Invalid2 {
375 fn re_borrow<'a: 'b, 'b>(arg: ArgumentOfType<'a, Self>) -> ArgumentOfType<'b, Self> {
376 match arg {}
377 }
378}
379
380impl ProvideArgument for Invalid {
381 type ProvideArgumentType = Invalid;
382
383 fn provide_argument_to<
388 Out,
389 F: for<'arg> FnOnce(ArgumentOfType<'arg, Self::ProvideArgumentType>) -> Out,
390 >(
391 &self,
392 _: F,
393 ) -> Out {
394 match *self {}
395 }
396}