1use self::sealed::*;
2
3pub use self::array::{ ArrayChain, ArrayMutChain };
4pub use self::string::{ StringChain, StringMutChain };
5pub use self::vec::{ VecChain, VecMutChain };
6
7mod array;
8mod string;
9mod vec;
10
11pub trait Chain: Sized + ChainSealed {
12 type Inner: ChainInner<Chain = Self>;
13
14 fn from_inner(inner: Self::Inner) -> Self;
15
16 #[inline]
17 fn into_inner(self) -> Self::Inner {
18 Self::Inner::from_chain(self)
19 }
20
21 fn with_inner(self, f: impl FnOnce(&mut Self::Inner)) -> Self;
45}
46
47pub trait ChainInner: Sized + ChainInnerSealed {
48 type Chain: Chain<Inner = Self>;
49
50 fn from_chain(chain: Self::Chain) -> Self;
51
52 #[inline]
53 fn into_chain(self) -> Self::Chain {
54 Self::Chain::from_inner(self)
55 }
56}
57
58pub trait ChainConversions
61where
62 Self: Sized + ChainConversionsSealed
63{
64 type Inner: Sized;
65 type MutChain<'mut_chain>: Sized
66 where
67 Self: 'mut_chain;
68
69 fn as_inner(&self) -> &Self::Inner;
70 fn as_inner_mut(&mut self) -> &mut Self::Inner;
71 fn as_mut_chain(&mut self) -> Self::MutChain<'_>;
72}
73
74impl<T> ChainConversions for &mut T
75where
76 T: ChainConversions
77{
78 type Inner = T::Inner;
79 type MutChain<'mut_chain> = T::MutChain<'mut_chain>
80 where
81 Self: 'mut_chain;
82
83 #[inline]
84 fn as_inner(&self) -> &Self::Inner {
85 (**self).as_inner()
86 }
87
88 #[inline]
89 fn as_inner_mut(&mut self) -> &mut Self::Inner {
90 (**self).as_inner_mut()
91 }
92
93 #[inline]
94 fn as_mut_chain(&mut self) -> Self::MutChain<'_> {
95 (**self).as_mut_chain()
96 }
97}
98
99impl<T> ChainConversionsSealed for &mut T
100where
101 T: ChainConversionsSealed
102{}
103
104pub trait WithSelf: Sized {
105 #[inline]
108 fn with_self<Void>(mut self, f: impl FnOnce(&mut Self) -> Void) -> Self {
109 let _ = f(&mut self);
110 self
111 }
112}
113
114impl<T> WithSelf for T {}
115
116pub unsafe trait Output<T>: Sized + OutputSealed<T> {
126 fn write(self, item: T);
128}
129
130unsafe impl<T> Output<T> for &mut T {
132 #[expect(
133 clippy::inline_always,
134 reason = "same as MaybeUninit::write"
135 )]
136 #[inline(always)]
137 fn write(self, item: T) {
138 *self = item;
139 }
140}
141impl<T> OutputSealed<T> for &mut T {}
142
143unsafe impl<T> Output<T> for &mut Option<T> {
145 #[expect(
146 clippy::inline_always,
147 reason = "same as MaybeUninit::write"
148 )]
149 #[inline(always)]
150 fn write(self, item: T) {
151 *self = Some(item);
152 }
153}
154impl<T> OutputSealed<T> for &mut Option<T> {}
155
156unsafe impl<T> Output<T> for &mut core::mem::MaybeUninit<T> {
158 #[expect(
159 clippy::inline_always,
160 reason = "same as MaybeUninit::write"
161 )]
162 #[inline(always)]
163 fn write(self, item: T) {
164 self.write(item);
165 }
166}
167impl<T> OutputSealed<T> for &mut core::mem::MaybeUninit<T> {}
168
169#[inline]
172pub fn out_dbg<T, O: Output<T>>(out: O) -> OutputDebug<T, O> {
173 OutputDebug { inner: out, __marker: std::marker::PhantomData }
174}
175
176#[repr(transparent)]
177pub struct OutputDebug<T, O>
178where
179 O: Output<T>
180{
181 inner: O,
182 __marker: core::marker::PhantomData<fn(T)>
183}
184
185impl<T, O> OutputDebug<T, O>
186where
187 O: Output<T>
188{
189 #[inline]
190 pub fn into_inner(self) -> O {
191 #[cfg(debug_assertions)]
194 let inner = {
195 let this = core::mem::ManuallyDrop::new(self);
196
197 unsafe { core::ptr::read(&this.inner) }
199 };
200
201 #[cfg(not(debug_assertions))]
204 let inner = self.inner;
205
206 inner
207 }
208}
209
210unsafe impl<T, O> Output<T> for OutputDebug<T, O>
212where
213 O: Output<T>
214{
215 #[inline]
216 fn write(self, item: T) {
217 self.into_inner().write(item);
218 }
219}
220impl<T, O> OutputSealed<T> for OutputDebug<T, O>
221where
222 O: Output<T>
223{}
224
225#[cfg(debug_assertions)]
226impl<T, O> Drop for OutputDebug<T, O>
227where
228 O: Output<T>
229{
230 #[inline]
231 fn drop(&mut self) {
232 panic!("`write` not called on created instance of `Output` (this is probably a bug)")
233 }
234}
235
236macro_rules! decl_chain {
237 {
238 $(#[$meta:meta])*
239 struct $chain:ident;
240 inner $inner:ty;
241 } => {
242 $crate::decl_chain! {
243 $(#[$meta])*
244 struct $chain[];
245 impl[] $chain;
246 inner $inner;
247 }
248 };
249
250 {
251 $(#[$meta:meta])*
252 struct $chain:ident[$($chain_decl_generics:tt)*];
253 impl[$($chain_impl_generics:tt)*] $chain_impl:ty;
254 $(where { $($where:tt)* };)?
255 inner $inner:ty;
256 } => {
257 $(#[$meta])*
258 #[must_use = "a chain always takes ownership of itself, performs the operation, then returns itself again"]
259 #[repr(transparent)]
260 pub struct $chain<$($chain_decl_generics)*>
261 $(where $($where)*)?
262 {
263 __inner: $inner
264 }
265
266 impl<$($chain_impl_generics)*> $crate::Chain for $chain_impl
267 $(where $($where)*)?
268 {
269 type Inner = $inner;
270
271 #[inline]
272 fn from_inner(inner: $inner) -> Self {
273 Self { __inner: inner }
274 }
275
276 #[inline]
277 fn with_inner(mut self, f: impl FnOnce(&mut Self::Inner)) -> Self {
278 let _ = f(&mut self.__inner);
279 self
280 }
281 }
282
283 impl<$($chain_impl_generics)*> $crate::ChainInner for $inner
284 $(where $($where)*)?
285 {
286 type Chain = $chain_impl;
287
288 #[inline]
289 fn from_chain(chain: $chain_impl) -> Self {
290 chain.__inner
291 }
292 }
293
294 impl<$($chain_impl_generics)*> $crate::ChainSealed for $chain_impl
295 $(where $($where)*)?
296 {}
297
298 impl<$($chain_impl_generics)*> $crate::ChainInnerSealed for $inner
299 $(where $($where)*)?
300 {}
301
302 impl<$($chain_impl_generics)*> ::core::clone::Clone for $chain_impl
303 where
304 $inner: ::core::clone::Clone
305 {
306 #[inline]
307 fn clone(&self) -> Self {
308 let clone = <$inner as ::core::clone::Clone>::clone(&self.__inner);
309 <Self as $crate::Chain>::from_inner(clone)
310 }
311
312 #[inline]
313 fn clone_from(&mut self, other: &Self) {
314 <$inner as ::core::clone::Clone>::clone_from(
315 &mut self.__inner,
316 &other.__inner
317 );
318 }
319 }
320
321 impl<$($chain_impl_generics)*> ::core::default::Default for $chain_impl
322 where
323 $inner: ::core::default::Default
324 {
325 #[inline]
326 fn default() -> Self {
327 let default = <$inner as ::core::default::Default>::default();
328 <Self as $crate::Chain>::from_inner(default)
329 }
330 }
331
332 };
343}
344use decl_chain;
345
346macro_rules! impl_chain_conversions {
347 {
348 impl chain [$($impl_chain_generics:tt)*] $impl_chain:ty;
349 impl chain_mut [$($impl_chain_mut_generics:tt)*] $impl_chain_mut:ty;
350 impl inner [$($impl_inner_generics:tt)*] $impl_inner:ty;
351 type inner $inner_type:ty;
352 type mut_chain $mut_chain_type:ty;
353 } => {
354 impl<$($impl_chain_generics)*> $crate::ChainConversions for $impl_chain {
355 type Inner = $inner_type;
356 type MutChain<'mut_chain> = $mut_chain_type
357 where
358 Self: 'mut_chain;
359
360 #[inline]
361 fn as_inner(&self) -> &Self::Inner {
362 &self.__inner
363 }
364
365 #[inline]
366 fn as_inner_mut(&mut self) -> &mut Self::Inner {
367 &mut self.__inner
368 }
369
370 #[inline]
371 fn as_mut_chain(&mut self) -> Self::MutChain<'_> {
372 Self::MutChain { __inner: &mut self.__inner }
373 }
374 }
375
376 impl<$($impl_chain_mut_generics)*> $crate::ChainConversions for $impl_chain_mut {
377 type Inner = $inner_type;
378 type MutChain<'mut_chain> = $mut_chain_type
379 where
380 Self: 'mut_chain;
381
382 #[inline]
383 fn as_inner(&self) -> &Self::Inner {
384 self.__inner
385 }
386
387 #[inline]
388 fn as_inner_mut(&mut self) -> &mut Self::Inner {
389 self.__inner
390 }
391
392 #[inline]
393 fn as_mut_chain(&mut self) -> Self::MutChain<'_> {
394 Self::MutChain { __inner: self.__inner }
395 }
396 }
397
398 impl<$($impl_inner_generics)*> $crate::ChainConversions for $impl_inner {
399 type Inner = $inner_type;
400 type MutChain<'mut_chain> = $mut_chain_type
401 where
402 Self: 'mut_chain;
403
404 #[inline]
405 fn as_inner(&self) -> &Self::Inner {
406 self
407 }
408
409 #[inline]
410 fn as_inner_mut(&mut self) -> &mut Self::Inner {
411 self
412 }
413
414 #[inline]
415 fn as_mut_chain(&mut self) -> Self::MutChain<'_> {
416 Self::MutChain { __inner: self }
417 }
418 }
419
420 impl<$($impl_chain_generics)*> $crate::ChainConversionsSealed for $impl_chain {}
421 impl<$($impl_chain_mut_generics)*> $crate::ChainConversionsSealed for $impl_chain_mut {}
422 impl<$($impl_inner_generics)*> $crate::ChainConversionsSealed for $impl_inner {}
423 };
424}
425use impl_chain_conversions;
426
427macro_rules! chain_fns {
428 {
429 impl chain [$($impl_chain_generics:tt)*] $impl_chain:ty;
430 impl chain_mut [$($impl_chain_mut_generics:tt)*] $impl_chain_mut:ty;
431
432 $($stuff:tt)*
433 } => {
434 impl<$($impl_chain_generics)*> $impl_chain {
435 $crate::chain_fns! { @impl $($stuff)* }
436 }
437
438 impl<$($impl_chain_mut_generics)*> $impl_chain_mut {
439 $crate::chain_fns! { @impl $($stuff)* }
440 }
441 };
442
443 {
444 @impl
445 $(underlying_fn $underlying_fn:literal $(($underlying_fn_link_to:literal))?)?
446 $(#[$meta:meta])*
447 fn $fn_name:ident$([$($generics:tt)*])?
448 ($inner:ident $($params:tt)*)
449 $(where { $($where:tt)* })?
450 { $($impl:tt)* }
451
452 $($stuff:tt)*
453 } => {
454 #[inline]
455 #[warn(missing_docs)]
456 $(#[$meta])*
457 $(
458 #[doc = ""]
459 #[doc = concat!(
460 "See documentation for [`",
461 $underlying_fn,
462 "`]",
463 $(
464 "(",
465 $underlying_fn_link_to,
466 ")",
467 )?
468 " for more details on the underlying function."
469 )]
470 )?
471 pub fn $fn_name$(<$($generics)*>)?(mut self $($params)*) -> Self
472 $(where $($where)*)?
473 {
474 let $inner = <Self as $crate::ChainConversions>::as_inner_mut(&mut self);
475 let _: () = { $($impl)* };
476 self
477 }
478
479 $crate::chain_fns! { @impl $($stuff)* }
480 };
481
482 {
483 @impl
484 $(underlying_fn $underlying_fn:literal $(($underlying_fn_link_to:literal))?)?
485 $(#[$meta:meta])*
486 unsafe fn $fn_name:ident$([$($generics:tt)*])?
487 ($inner:ident $($params:tt)*)
488 $(where { $($where:tt)* })?
489 { $($impl:tt)* }
490
491 $($stuff:tt)*
492 } => {
493 #[inline]
494 #[warn(missing_docs)]
495 $(#[$meta])*
496 $(
497 #[doc = ""]
498 #[doc = "# Safety"]
499 #[doc = ""]
500 #[doc = concat!(
501 "You must uphold safety invariants of [`",
502 $underlying_fn,
503 "`]",
504 $(
505 "(",
506 $underlying_fn_link_to,
507 ")",
508 )?
509 "."
510 )]
511 #[doc = ""]
512 #[doc = concat!(
513 "See documentation for [`",
514 $underlying_fn,
515 "`]",
516 $(
517 "(",
518 $underlying_fn_link_to,
519 ")",
520 )?
521 " for more details on the underlying function."
522 )]
523 )?
524 pub unsafe fn $fn_name$(<$($generics)*>)?(mut self $($params)*) -> Self
525 $(where $($where)*)?
526 {
527 let $inner = <Self as $crate::ChainConversions>::as_inner_mut(&mut self);
528 let _: () = { $($impl)* };
529 self
530 }
531
532 $crate::chain_fns! { @impl $($stuff)* }
533 };
534
535 { @impl } => {};
536}
537use chain_fns;
538
539mod sealed {
541 pub trait ChainSealed {}
543
544 pub trait ChainInnerSealed {}
546
547 pub trait OutputSealed<T> {}
549
550 pub trait ChainConversionsSealed {}
552}