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]
174pub fn out_dbg<T, O: Output<T>>(out: O) -> OutputDebug<T, O> {
175 OutputDebug {
176 inner: out,
177 __marker: std::marker::PhantomData
178 }
179}
180
181#[repr(transparent)]
182pub struct OutputDebug<T, O>
183where
184 O: Output<T>
185{
186 inner: O,
187 __marker: core::marker::PhantomData<fn(T)>
188}
189
190impl<T, O> OutputDebug<T, O>
191where
192 O: Output<T>
193{
194 #[inline]
196 pub fn into_inner(self) -> O {
197 #[cfg(debug_assertions)]
200 let inner = {
201 let this = core::mem::ManuallyDrop::new(self);
202
203 unsafe { core::ptr::read(&raw const this.inner) }
205 };
206
207 #[cfg(not(debug_assertions))]
210 let inner = self.inner;
211
212 inner
213 }
214}
215
216unsafe impl<T, O> Output<T> for OutputDebug<T, O>
218where
219 O: Output<T>
220{
221 #[inline]
222 fn write(self, item: T) {
223 self.into_inner().write(item);
224 }
225}
226
227impl<T, O> OutputSealed<T> for OutputDebug<T, O>
228where
229 O: Output<T>
230{}
231
232#[cfg(debug_assertions)]
233impl<T, O> Drop for OutputDebug<T, O>
234where
235 O: Output<T>
236{
237 #[inline]
238 fn drop(&mut self) {
239 panic!("`write` not called on created instance of `Output` (this is probably a bug)")
242 }
243}
244
245macro_rules! decl_chain {
246 {
247 $(#[$meta:meta])*
248 struct $chain:ident;
249 inner $inner:ty;
250 } => {
251 $crate::decl_chain! {
252 $(#[$meta])*
253 struct $chain[];
254 impl[] $chain;
255 inner $inner;
256 }
257 };
258
259 {
260 $(#[$meta:meta])*
261 struct $chain:ident[$($chain_decl_generics:tt)*];
262 impl[$($chain_impl_generics:tt)*] $chain_impl:ty;
263 $(where { $($where:tt)* };)?
264 inner $inner:ty;
265 } => {
266 $(#[$meta])*
267 #[must_use = "a chain always takes ownership of itself, performs the operation, then returns itself again"]
268 #[repr(transparent)]
269 pub struct $chain<$($chain_decl_generics)*>
270 $(where $($where)*)?
271 {
272 __inner: $inner
273 }
274
275 impl<$($chain_impl_generics)*> $crate::Chain for $chain_impl
276 $(where $($where)*)?
277 {
278 type Inner = $inner;
279
280 #[inline]
281 fn from_inner(inner: $inner) -> Self {
282 Self { __inner: inner }
283 }
284
285 #[inline]
286 fn with_inner(mut self, f: impl FnOnce(&mut Self::Inner)) -> Self {
287 let _ = f(&mut self.__inner);
288 self
289 }
290 }
291
292 impl<$($chain_impl_generics)*> $crate::ChainInner for $inner
293 $(where $($where)*)?
294 {
295 type Chain = $chain_impl;
296
297 #[inline]
298 fn from_chain(chain: $chain_impl) -> Self {
299 chain.__inner
300 }
301 }
302
303 impl<$($chain_impl_generics)*> $crate::ChainSealed for $chain_impl
304 $(where $($where)*)?
305 {}
306
307 impl<$($chain_impl_generics)*> $crate::ChainInnerSealed for $inner
308 $(where $($where)*)?
309 {}
310
311 impl<$($chain_impl_generics)*> ::core::clone::Clone for $chain_impl
312 where
313 $inner: ::core::clone::Clone
314 {
315 #[inline]
316 fn clone(&self) -> Self {
317 let clone = <$inner as ::core::clone::Clone>::clone(&self.__inner);
318 <Self as $crate::Chain>::from_inner(clone)
319 }
320
321 #[inline]
322 fn clone_from(&mut self, other: &Self) {
323 <$inner as ::core::clone::Clone>::clone_from(
324 &mut self.__inner,
325 &other.__inner
326 );
327 }
328 }
329
330 impl<$($chain_impl_generics)*> ::core::default::Default for $chain_impl
331 where
332 $inner: ::core::default::Default
333 {
334 #[inline]
335 fn default() -> Self {
336 let default = <$inner as ::core::default::Default>::default();
337 <Self as $crate::Chain>::from_inner(default)
338 }
339 }
340
341 };
352}
353use decl_chain;
354
355macro_rules! impl_chain_conversions {
356 {
357 impl chain [$($impl_chain_generics:tt)*] $impl_chain:ty;
358 impl chain_mut [$($impl_chain_mut_generics:tt)*] $impl_chain_mut:ty;
359 impl inner [$($impl_inner_generics:tt)*] $impl_inner:ty;
360 type inner $inner_type:ty;
361 type mut_chain $mut_chain_type:ty;
362 } => {
363 impl<$($impl_chain_generics)*> $crate::ChainConversions for $impl_chain {
364 type Inner = $inner_type;
365 type MutChain<'mut_chain> = $mut_chain_type
366 where
367 Self: 'mut_chain;
368
369 #[inline]
370 fn as_inner(&self) -> &Self::Inner {
371 &self.__inner
372 }
373
374 #[inline]
375 fn as_inner_mut(&mut self) -> &mut Self::Inner {
376 &mut self.__inner
377 }
378
379 #[inline]
380 fn as_mut_chain(&mut self) -> Self::MutChain<'_> {
381 Self::MutChain { __inner: &mut self.__inner }
382 }
383 }
384
385 impl<$($impl_chain_mut_generics)*> $crate::ChainConversions for $impl_chain_mut {
386 type Inner = $inner_type;
387 type MutChain<'mut_chain> = $mut_chain_type
388 where
389 Self: 'mut_chain;
390
391 #[inline]
392 fn as_inner(&self) -> &Self::Inner {
393 self.__inner
394 }
395
396 #[inline]
397 fn as_inner_mut(&mut self) -> &mut Self::Inner {
398 self.__inner
399 }
400
401 #[inline]
402 fn as_mut_chain(&mut self) -> Self::MutChain<'_> {
403 Self::MutChain { __inner: self.__inner }
404 }
405 }
406
407 impl<$($impl_inner_generics)*> $crate::ChainConversions for $impl_inner {
408 type Inner = $inner_type;
409 type MutChain<'mut_chain> = $mut_chain_type
410 where
411 Self: 'mut_chain;
412
413 #[inline]
414 fn as_inner(&self) -> &Self::Inner {
415 self
416 }
417
418 #[inline]
419 fn as_inner_mut(&mut self) -> &mut Self::Inner {
420 self
421 }
422
423 #[inline]
424 fn as_mut_chain(&mut self) -> Self::MutChain<'_> {
425 Self::MutChain { __inner: self }
426 }
427 }
428
429 impl<$($impl_chain_generics)*> $crate::ChainConversionsSealed for $impl_chain {}
430 impl<$($impl_chain_mut_generics)*> $crate::ChainConversionsSealed for $impl_chain_mut {}
431 impl<$($impl_inner_generics)*> $crate::ChainConversionsSealed for $impl_inner {}
432 };
433}
434use impl_chain_conversions;
435
436macro_rules! chain_fns {
437 {
438 impl chain [$($impl_chain_generics:tt)*] $impl_chain:ty;
439 impl chain_mut [$($impl_chain_mut_generics:tt)*] $impl_chain_mut:ty;
440
441 $($stuff:tt)*
442 } => {
443 impl<$($impl_chain_generics)*> $impl_chain {
444 $crate::chain_fns! { @impl $($stuff)* }
445 }
446
447 impl<$($impl_chain_mut_generics)*> $impl_chain_mut {
448 $crate::chain_fns! { @impl $($stuff)* }
449 }
450 };
451
452 {
453 @impl
454 $(underlying_fn $underlying_fn:literal $(($underlying_fn_link_to:literal))?)?
455 $(#[$meta:meta])*
456 fn $fn_name:ident$([$($generics:tt)*])?
457 ($inner:ident $($params:tt)*)
458 $(where { $($where:tt)* })?
459 { $($impl:tt)* }
460
461 $($stuff:tt)*
462 } => {
463 #[inline]
464 #[warn(missing_docs)]
465 $(#[$meta])*
466 $(
467 #[doc = ""]
468 #[doc = concat!(
469 "See documentation for [`",
470 $underlying_fn,
471 "`]",
472 $(
473 "(",
474 $underlying_fn_link_to,
475 ")",
476 )?
477 " for more details on the underlying function."
478 )]
479 )?
480 pub fn $fn_name$(<$($generics)*>)?(mut self $($params)*) -> Self
481 $(where $($where)*)?
482 {
483 let $inner = <Self as $crate::ChainConversions>::as_inner_mut(&mut self);
484 let _: () = { $($impl)* };
485 self
486 }
487
488 $crate::chain_fns! { @impl $($stuff)* }
489 };
490
491 {
492 @impl
493 $(underlying_fn $underlying_fn:literal $(($underlying_fn_link_to:literal))?)?
494 $(#[$meta:meta])*
495 unsafe fn $fn_name:ident$([$($generics:tt)*])?
496 ($inner:ident $($params:tt)*)
497 $(where { $($where:tt)* })?
498 { $($impl:tt)* }
499
500 $($stuff:tt)*
501 } => {
502 #[inline]
503 #[warn(missing_docs)]
504 $(#[$meta])*
505 $(
506 #[doc = ""]
507 #[doc = "# Safety"]
508 #[doc = ""]
509 #[doc = concat!(
510 "You must uphold safety invariants of [`",
511 $underlying_fn,
512 "`]",
513 $(
514 "(",
515 $underlying_fn_link_to,
516 ")",
517 )?
518 "."
519 )]
520 #[doc = ""]
521 #[doc = concat!(
522 "See documentation for [`",
523 $underlying_fn,
524 "`]",
525 $(
526 "(",
527 $underlying_fn_link_to,
528 ")",
529 )?
530 " for more details on the underlying function."
531 )]
532 )?
533 pub unsafe fn $fn_name$(<$($generics)*>)?(mut self $($params)*) -> Self
534 $(where $($where)*)?
535 {
536 let $inner = <Self as $crate::ChainConversions>::as_inner_mut(&mut self);
537 let _: () = { $($impl)* };
538 self
539 }
540
541 $crate::chain_fns! { @impl $($stuff)* }
542 };
543
544 { @impl } => {};
545}
546use chain_fns;
547
548mod sealed {
550 pub trait ChainSealed {}
552
553 pub trait ChainInnerSealed {}
555
556 pub trait OutputSealed<T> {}
558
559 pub trait ChainConversionsSealed {}
561}