wiwi_chain/
lib.rs

1use core::fmt::{ self, Debug, Display };
2use core::hash::{ Hash, Hasher };
3#[cfg(feature = "serde")]
4use serde::{ Deserialize, Deserializer, Serialize, Serializer };
5
6pub mod types;
7
8mod array;
9mod map;
10mod set;
11mod string;
12mod vec;
13
14#[must_use = "a chain always takes ownership of itself, performs the operation, then returns itself again"]
15#[repr(transparent)]
16pub struct Chain<T> {
17	__inner: T
18}
19
20impl<T> Chain<T> {
21	#[inline]
22	pub fn from_inner(inner: T) -> Self {
23		Self { __inner: inner }
24	}
25
26	#[inline]
27	pub fn into_inner(self) -> T {
28		T::from_chain(self)
29	}
30
31	#[inline]
32	pub fn as_inner(&self) -> &T {
33		&self.__inner
34	}
35
36	#[inline]
37	pub fn as_inner_mut(&mut self) -> &mut T {
38		&mut self.__inner
39	}
40
41	/// Takes a closure that is called, passing in a reference to the inner value
42	///
43	/// This is useful for if there is something we have not implemented, or you
44	/// otherwise need to borrow the inner struct for something, but are in the
45	/// middle of some chain. It lets you do otherwise nonchainable operations
46	/// inline with other chaining operations, so no need to break the chain c:
47	///
48	/// # Examples
49	///
50	// todo fix and unignore this
51	/// ```ignore
52	/// # use wiwi_chain::{ Chain as _, VecChain };
53	/// let chain = VecChain::<usize>::new();
54	///
55	/// // let's pretend `push` and `reserve` don't already have chainable versions...
56	/// let chain = chain
57	///    .with_inner(|v| v.reserve(10))
58	///    .with_inner(|v| v.push(1))
59	///    .with_inner(|v| v.push(2));
60	///
61	/// assert!(chain.as_inner().len() == 2);
62	/// assert!(chain.as_inner().capacity() >= 10);
63	/// ```
64	#[inline]
65	pub fn with_inner(mut self, f: impl FnOnce(&mut T)) -> Self {
66		f(self.as_inner_mut());
67		self
68	}
69}
70
71impl<T> Chain<&T> {
72	#[inline]
73	pub fn cloned(&self) -> Chain<T>
74	where
75		T: Clone
76	{
77		(**self.as_inner()).clone().into_chain()
78	}
79
80	#[inline]
81	pub fn copied(&self) -> Chain<T>
82	where
83		T: Copy
84	{
85		(**self.as_inner()).into_chain()
86	}
87}
88
89impl<T> Chain<&mut T> {
90	#[inline]
91	pub fn cloned(&self) -> Chain<T>
92	where
93		T: Clone
94	{
95		(**self.as_inner()).clone().into_chain()
96	}
97
98	#[inline]
99	pub fn copied(&self) -> Chain<T>
100	where
101		T: Copy
102	{
103		(**self.as_inner()).into_chain()
104	}
105}
106
107impl<'h, T> Chain<&'h &'h T> {
108	#[inline]
109	pub fn flatten(self) -> Chain<&'h T> {
110		(*self.into_inner()).into_chain()
111	}
112}
113
114impl<'h, T> Chain<&'h mut &'h mut T> {
115	#[inline]
116	pub fn flatten(self) -> Chain<&'h mut T> {
117		(*self.into_inner()).into_chain()
118	}
119}
120
121impl<T> Chain<Chain<T>> {
122	#[inline]
123	pub fn flatten(self) -> Chain<T> {
124		self.into_inner()
125	}
126
127	// ?????
128	// #[inline]
129	// pub fn as_flattened(&self) -> Chain<&T> {
130	// 	Chain { inner: &self.inner.inner }
131	// }
132
133	// ?????
134	// #[inline]
135	// pub fn as_flattened_mut(&mut self) -> Chain<&mut T> {
136	// 	Chain { inner: &mut self.inner.inner }
137	// }
138}
139
140// todo I'm not even sure if we should have these below 2 implementations
141
142// impl<'h, T> Chain<&'h &'h mut T> {
143// 	#[inline]
144// 	pub fn flatten(self) -> Chain<&'h T> {
145// 		Chain { inner: self.inner }
146// 	}
147// }
148
149// impl<'h, T> Chain<&'h mut &'h T> {
150// 	#[inline]
151// 	pub fn flatten(self) -> Chain<&'h T> {
152// 		Chain { inner: self.inner }
153// 	}
154// }
155
156impl<T, T2> AsRef<T2> for Chain<T>
157where
158	T: AsRef<T2>
159{
160	#[inline]
161	fn as_ref(&self) -> &T2 {
162		T::as_ref(self.as_inner())
163	}
164}
165
166impl<T, T2> AsMut<T2> for Chain<T>
167where
168	T: AsMut<T2>
169{
170	#[inline]
171	fn as_mut(&mut self) -> &mut T2 {
172		T::as_mut(self.as_inner_mut())
173	}
174}
175
176impl<T> Clone for Chain<T>
177where
178	T: Clone
179{
180	#[inline]
181	fn clone(&self) -> Self {
182		T::clone(self.as_inner()).into_chain()
183	}
184
185	#[inline]
186	fn clone_from(&mut self, source: &Self) {
187		T::clone_from(self.as_inner_mut(), source.as_inner())
188	}
189}
190
191impl<T> Copy for Chain<T>
192where
193	T: Copy
194{}
195
196impl<T> Debug for Chain<T>
197where
198	T: Debug
199{
200	#[inline]
201	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
202		f.debug_struct("Chain<T>")
203			.field("_", self.as_inner())
204			.finish()
205	}
206}
207
208impl<T> Default for Chain<T>
209where
210	T: Default
211{
212	#[inline]
213	fn default() -> Self {
214		T::default().into_chain()
215	}
216}
217
218#[cfg(feature = "serde")]
219impl<'de, T> Deserialize<'de> for Chain<T>
220where
221	T: Deserialize<'de>
222{
223	#[inline]
224	fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
225	where
226		D: Deserializer<'de>
227	{
228		T::deserialize(deserializer)
229			.map(|inner| inner.into_chain())
230	}
231}
232
233impl<T> Display for Chain<T>
234where
235	T: Display
236{
237	#[inline]
238	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
239		T::fmt(self.as_inner(), f)
240	}
241}
242
243// todo eq
244
245impl<T> Hash for Chain<T>
246where
247	T: Hash
248{
249	#[inline]
250	fn hash<H: Hasher>(&self, state: &mut H) {
251		T::hash(self.as_inner(), state)
252	}
253
254	#[inline]
255	fn hash_slice<H: Hasher>(data: &[Self], state: &mut H) {
256		#[expect(clippy::as_conversions, reason = "ptr cast")]
257		let ptr = &raw const *data as *const [T];
258
259		// SAFETY: we are repr(transparent),
260		// cast ptr is safe to deref
261		let data = unsafe { &*ptr };
262
263		T::hash_slice(data, state)
264	}
265}
266
267// todo Hasher...?
268
269impl<T> IntoIterator for Chain<T>
270where
271	T: IntoIterator
272{
273	type Item = T::Item;
274	type IntoIter = T::IntoIter;
275
276	#[inline]
277	fn into_iter(self) -> T::IntoIter {
278		self.into_inner().into_iter()
279	}
280}
281
282impl<'h, T> IntoIterator for &'h Chain<T>
283where
284	&'h T: IntoIterator
285{
286	type Item = <&'h T as IntoIterator>::Item;
287	type IntoIter = <&'h T as IntoIterator>::IntoIter;
288
289	#[inline]
290	fn into_iter(self) -> <&'h T as IntoIterator>::IntoIter {
291		self.as_inner().into_iter()
292	}
293}
294
295impl<'h, T> IntoIterator for &'h mut Chain<T>
296where
297	&'h mut T: IntoIterator
298{
299	type Item = <&'h mut T as IntoIterator>::Item;
300	type IntoIter = <&'h mut T as IntoIterator>::IntoIter;
301
302	#[inline]
303	fn into_iter(self) -> <&'h mut T as IntoIterator>::IntoIter {
304		self.as_inner_mut().into_iter()
305	}
306}
307
308// todo ord
309
310impl<T, T2> PartialEq<T2> for Chain<T>
311where
312	T: PartialEq<T2>
313{
314	#[inline]
315	fn eq(&self, other: &T2) -> bool {
316		T::eq(self.as_inner(), other)
317	}
318
319	#[expect(
320		clippy::partialeq_ne_impl,
321		reason = "inner might have overridden ne for whatever reason, and we should use it if so"
322	)]
323	#[inline]
324	fn ne(&self, other: &T2) -> bool {
325		T::ne(self.as_inner(), other)
326	}
327}
328
329#[cfg(feature = "serde")]
330impl<T> Serialize for Chain<T>
331where
332	T: Serialize
333{
334	#[inline]
335	fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
336	where
337		S: Serializer
338	{
339		T::serialize(self.as_inner(), serializer)
340	}
341}
342
343// todo partialord
344
345pub trait ChainInner: Sized {
346	#[inline]
347	fn from_chain(chain: Chain<Self>) -> Self {
348		chain.into_inner()
349	}
350
351	#[inline]
352	fn into_chain(self) -> Chain<Self> {
353		Chain::from_inner(self)
354	}
355
356	#[inline]
357	fn chain_mut(&mut self) -> Chain<&mut Self> {
358		Chain::from_inner(self)
359	}
360}
361
362impl<T> ChainInner for T {}
363
364/// Trait implemented on chains and their inner types, allowing you to get a reference
365/// to the inner type regardless of if the chain or the inner type is passed in
366pub trait ChainConversions
367where
368	Self: Sized + self::sealed::chain_conversions::Sealed
369{
370	type Inner: Sized;
371	type MutChain<'mut_chain>: Sized
372	where
373		Self: 'mut_chain;
374
375	fn as_inner(&self) -> &Self::Inner;
376	fn as_inner_mut(&mut self) -> &mut Self::Inner;
377	fn as_mut_chain(&mut self) -> Self::MutChain<'_>;
378}
379
380impl<T> ChainConversions for &mut T
381where
382	T: ChainConversions
383{
384	type Inner = T::Inner;
385	type MutChain<'mut_chain> = T::MutChain<'mut_chain>
386	where
387		Self: 'mut_chain;
388
389	#[inline]
390	fn as_inner(&self) -> &Self::Inner {
391		(**self).as_inner()
392	}
393
394	#[inline]
395	fn as_inner_mut(&mut self) -> &mut Self::Inner {
396		(**self).as_inner_mut()
397	}
398
399	#[inline]
400	fn as_mut_chain(&mut self) -> Self::MutChain<'_> {
401		(**self).as_mut_chain()
402	}
403}
404
405impl<T> self::sealed::chain_conversions::Sealed for &mut T
406where
407	T: self::sealed::chain_conversions::Sealed
408{}
409
410pub trait ChainConversionsOwned: ChainConversions {
411	type OwnedChain: Sized;
412
413	fn into_chain(self) -> Self::OwnedChain;
414	fn into_inner(self) -> Self::Inner;
415}
416
417pub trait WithSelf: Sized {
418	/// Takes ownership of the value, passing a mutable reference of it to a
419	/// closure, then returning ownership of the value again
420	#[inline]
421	fn with_self(mut self, f: impl FnOnce(&mut Self)) -> Self {
422		f(&mut self);
423		self
424	}
425}
426
427impl<T> WithSelf for T {}
428
429/// # Safety
430///
431/// By using this trait, implementors of functions are promising to call
432/// [`write`](Output::write), so that when the function returns, there is a
433/// value written to the output. For example, users can pass a reference to
434/// [`MaybeUninit`](core::mem::MaybeUninit) and rely on the fact that it got
435/// initialised to safely call [`assume_init`](core::mem::MaybeUninit::assume_init).
436///
437/// idk how to enforce the above properly using unsafe etc.
438pub unsafe trait Output<T>: Sized + self::sealed::output::Sealed<T> {
439	/// Stores a value
440	fn write(self, item: T);
441}
442
443// SAFETY: we write once to `self`
444unsafe impl<T> Output<T> for &mut T {
445	#[expect(
446		clippy::inline_always,
447		reason = "same as MaybeUninit::write"
448	)]
449	#[inline(always)]
450	fn write(self, item: T) {
451		*self = item;
452	}
453}
454impl<T> self::sealed::output::Sealed<T> for &mut T {}
455
456// SAFETY: we write once to `self`
457unsafe impl<T> Output<T> for &mut Option<T> {
458	#[expect(
459		clippy::inline_always,
460		reason = "same as MaybeUninit::write"
461	)]
462	#[inline(always)]
463	fn write(self, item: T) {
464		*self = Some(item);
465	}
466}
467impl<T> self::sealed::output::Sealed<T> for &mut Option<T> {}
468
469// SAFETY: we write once to `self`
470unsafe impl<T> Output<T> for &mut core::mem::MaybeUninit<T> {
471	#[expect(
472		clippy::inline_always,
473		reason = "same as MaybeUninit::write"
474	)]
475	#[inline(always)]
476	fn write(self, item: T) {
477		self.write(item);
478	}
479}
480impl<T> self::sealed::output::Sealed<T> for &mut core::mem::MaybeUninit<T> {}
481
482/// Tool for helping to debug [`Output`] trait usage in debug mode (if `out` is
483/// not written to, the function will panic)
484///
485/// This function should optimise out to a no-op in release mode.
486#[inline]
487pub fn out_dbg<T, O: Output<T>>(out: O) -> OutputDebug<T, O> {
488	OutputDebug {
489		inner: out,
490		__marker: std::marker::PhantomData
491	}
492}
493
494#[repr(transparent)]
495pub struct OutputDebug<T, O>
496where
497	O: Output<T>
498{
499	inner: O,
500	__marker: core::marker::PhantomData<fn(T)>
501}
502
503impl<T, O> OutputDebug<T, O>
504where
505	O: Output<T>
506{
507	/// Unwraps self and returns the inner output (without ever panicking)
508	#[inline]
509	pub fn into_inner(self) -> O {
510		// in cfg(debug_assertions), we have Drop impl,
511		// so we need to do a funny to get `inner` out
512		#[cfg(debug_assertions)]
513		let inner = {
514			let this = core::mem::ManuallyDrop::new(self);
515
516			// SAFETY: ManuallyDrop above prevents double drops
517			unsafe { core::ptr::read(&raw const this.inner) }
518		};
519
520		// in not(cfg(debug_assertions)), we don't have
521		// Drop impl, so we can just normally move it out
522		#[cfg(not(debug_assertions))]
523		let inner = self.inner;
524
525		inner
526	}
527}
528
529// SAFETY: we write once to `self`
530unsafe impl<T, O> Output<T> for OutputDebug<T, O>
531where
532	O: Output<T>
533{
534	#[inline]
535	fn write(self, item: T) {
536		self.into_inner().write(item);
537	}
538}
539
540impl<T, O> self::sealed::output::Sealed<T> for OutputDebug<T, O>
541where
542	O: Output<T>
543{}
544
545#[cfg(debug_assertions)]
546impl<T, O> Drop for OutputDebug<T, O>
547where
548	O: Output<T>
549{
550	#[inline]
551	fn drop(&mut self) {
552		// writing to this slot will prevent this panic from being called (via ManuallyDrop)
553		// additionally this drop impl only is enabled if debug assertions is enabled
554		panic!("`write` not called on created instance of `Output` (this is probably a bug)")
555	}
556}
557
558macro_rules! impl_chain_conversions {
559	{
560		$(#[$meta:meta])*
561		[$($generics:tt)*] $inner:ty
562	} => {
563		$(#[$meta])*
564		impl<$($generics)*> $crate::ChainConversions for $crate::Chain<$inner> {
565			type Inner = $inner;
566			type MutChain<'mut_chain> = $crate::Chain<&'mut_chain mut $inner>
567			where
568				Self: 'mut_chain;
569
570			#[inline]
571			fn as_inner(&self) -> &Self::Inner {
572				$crate::Chain::as_inner(self)
573			}
574
575			#[inline]
576			fn as_inner_mut(&mut self) -> &mut Self::Inner {
577				$crate::Chain::as_inner_mut(self)
578			}
579
580			#[inline]
581			fn as_mut_chain(&mut self) -> $crate::Chain<&mut $inner> {
582				let inner = $crate::Chain::as_inner_mut(self);
583				$crate::Chain::from_inner(inner)
584			}
585		}
586
587		$(#[$meta])*
588		impl<'h, $($generics)*> $crate::ChainConversions for $crate::Chain<&'h mut $inner> {
589			type Inner = $inner;
590			type MutChain<'mut_chain> = $crate::Chain<&'mut_chain mut $inner>
591			where
592				Self: 'mut_chain;
593
594			#[inline]
595			fn as_inner(&self) -> &Self::Inner {
596				&**$crate::Chain::as_inner(self)
597			}
598
599			#[inline]
600			fn as_inner_mut(&mut self) -> &mut Self::Inner {
601				&mut **$crate::Chain::as_inner_mut(self)
602			}
603
604			#[inline]
605			fn as_mut_chain(&mut self) -> $crate::Chain<&mut $inner> {
606				let inner = $crate::Chain::as_inner_mut(self);
607				$crate::Chain::from_inner(&mut **inner)
608			}
609		}
610
611		$(#[$meta])*
612		impl<$($generics)*> $crate::ChainConversions for $inner {
613			type Inner = $inner;
614			type MutChain<'mut_chain> = $crate::Chain<&'mut_chain mut $inner>
615			where
616				Self: 'mut_chain;
617
618			#[inline]
619			fn as_inner(&self) -> &Self::Inner {
620				self
621			}
622
623			#[inline]
624			fn as_inner_mut(&mut self) -> &mut Self::Inner {
625				self
626			}
627
628			#[inline]
629			fn as_mut_chain(&mut self) -> $crate::Chain<&mut $inner> {
630				$crate::Chain::from_inner(self)
631			}
632		}
633
634		$(#[$meta])*
635		impl<$($generics)*> $crate::ChainConversionsOwned for $crate::Chain<$inner> {
636			type OwnedChain = $crate::Chain<$inner>;
637
638			#[inline]
639			fn into_chain(self) -> $crate::Chain<$inner> {
640				self
641			}
642
643			#[inline]
644			fn into_inner(self) -> $inner {
645				$crate::Chain::into_inner(self)
646			}
647		}
648
649		$(#[$meta])*
650		impl<$($generics)*> $crate::ChainConversionsOwned for $inner {
651			type OwnedChain = $crate::Chain<$inner>;
652
653			#[inline]
654			fn into_chain(self) -> $crate::Chain<$inner> {
655				$crate::Chain::from_inner(self)
656			}
657
658			#[inline]
659			fn into_inner(self) -> $inner {
660				self
661			}
662		}
663
664		$(#[$meta])*
665		impl<$($generics)*> $crate::sealed::chain_conversions::Sealed for $crate::Chain<$inner> {}
666		$(#[$meta])*
667		impl<'h, $($generics)*> $crate::sealed::chain_conversions::Sealed for $crate::Chain<&'h mut $inner> {}
668		$(#[$meta])*
669		impl<$($generics)*> $crate::sealed::chain_conversions::Sealed for $inner {}
670	};
671}
672use impl_chain_conversions;
673
674macro_rules! chain_fns {
675	{ @head @head @head @head @head $($stuff:tt)* } => {
676		compile_error!("you have huge brain use your own macro properly 5head");
677	};
678
679	{
680		@head
681		$(#[$meta:meta])*
682		impl [$($generics:tt)*] $({ doc $($doc_type:tt)* })? $inner:ty;
683
684		$($stuff:tt)*
685	} => {
686		#[warn(missing_docs)]
687		$(#[$meta])*
688		impl<$($generics)*> $crate::Chain<$inner> {
689			$crate::chain_fns! {
690				@impl
691				$({ doctype $($doc_type)* })?
692				$($stuff)*
693			}
694		}
695
696		$crate::chain_fns! {
697			@head
698			$($stuff)*
699		}
700	};
701
702	{
703		@head
704		$(#[$meta:meta])*
705		impl mut [$($generics:tt)*] $({ doc $($doc_type:tt)* })? $inner:ty;
706
707		$($stuff:tt)*
708	} => {
709		#[warn(missing_docs)]
710		$(#[$meta])*
711		impl<'h, $($generics)*> $crate::Chain<&'h mut $inner> {
712			$crate::chain_fns! {
713				@impl
714				$({ doctype $($doc_type)* })?
715				$($stuff)*
716			}
717		}
718
719		$crate::chain_fns! {
720			@head
721			$($stuff)*
722		}
723	};
724
725	{
726		@head
727		$(#[$meta:meta])*
728		impl ref [$($generics:tt)*] $({ doc $($doc_type:tt)* })? $inner:ty;
729
730		$($stuff:tt)*
731	} => {
732		#[warn(missing_docs)]
733		$(#[$meta])*
734		impl<'h, $($generics)*> $crate::Chain<&'h $inner> {
735			$crate::chain_fns! {
736				@impl
737				$({ doctype $($doc_type)* })?
738				$($stuff)*
739			}
740		}
741
742		$crate::chain_fns! {
743			@head
744			$($stuff)*
745		}
746	};
747
748	{
749		@head
750		$(#[$meta:meta])*
751		impl and_mut [$($generics:tt)*] $({ doc $($doc_type:tt)* })? $inner:ty;
752
753		$($stuff:tt)*
754	} => {
755		#[warn(missing_docs)]
756		$(#[$meta])*
757		impl<$($generics)*> $crate::Chain<$inner> {
758			$crate::chain_fns! {
759				@impl
760				$({ doctype $($doc_type)* })?
761				$($stuff)*
762			}
763		}
764
765		#[warn(missing_docs)]
766		$(#[$meta])*
767		impl<'h, $($generics)*> $crate::Chain<&'h mut $inner> {
768			$crate::chain_fns! {
769				@impl
770				$({ doctype $($doc_type)* })?
771				$($stuff)*
772			}
773		}
774
775		$crate::chain_fns! {
776			@head
777			$($stuff)*
778		}
779	};
780
781	{
782		@head
783		$(#[$meta:meta])*
784		impl $impl_type:ident $($stuff:tt)*
785	} => {
786		compile_error!(concat!(
787			"unrecognised impl type found: `",
788			stringify!($impl_type),
789			"`"
790		));
791	};
792
793	{
794		@head
795		$({ doctype $($doc_type:tt)* })?
796
797		$(doc [$($doc:tt)+]$(($($doc_link_to:tt)+))?)?
798		$(#[$meta:meta])*
799		fn
800		$($stuff:tt)*
801	} => {};
802
803	{
804		@head
805		$({ doctype $($doc_type:tt)* })?
806
807		$(doc [$($doc:tt)+]$(($($doc_link_to:tt)+))?)?
808		$(#[$meta:meta])*
809		unsafe fn
810		$($stuff:tt)*
811	} => {};
812
813	{ @head } => {};
814
815	{
816		@impl
817		$({ doctype $($doc_type:tt)* })?
818
819		$(#[$meta:meta])*
820		impl [$($generics:tt)*] $({ doc $($_doc_type:tt)* })? $inner:ty;
821
822		$($stuff:tt)*
823	} => {
824		$crate::chain_fns! {
825			@impl
826			$({ doctype $($doc_type)* })?
827			$($stuff)*
828		}
829	};
830
831	{
832		@impl
833		$({ doctype $($doc_type:tt)* })?
834
835		$(#[$meta:meta])*
836		impl $($impl_type:ident)? [$($generics:tt)*] $({ doc $($_doc_type:tt)* })? $inner:ty;
837
838		$($stuff:tt)*
839	} => {
840		$crate::chain_fns! {
841			@impl
842			$({ doctype $($doc_type)* })?
843			$($stuff)*
844		}
845	};
846
847	{
848		@impl
849		$({ doctype $($doc_type:tt)* })?
850
851		doc [Self]$(($($doc_link_to:tt)+))?
852		$(#[$meta:meta])*
853		fn $fn_name:ident
854
855		$($stuff:tt)*
856	} => {
857		$crate::chain_fns! {
858			@impl
859			$({ doctype $($doc_type)* })?
860
861			doc [Self::$fn_name]$(($($doc_link_to)+))?
862			$(#[$meta])*
863			fn $fn_name
864
865			$($stuff)*
866		}
867	};
868
869	{
870		@impl
871		$({ doctype $($doc_type:tt)* })?
872
873		doc [Self]$(($($doc_link_to:tt)+))?
874		$(#[$meta:meta])*
875		unsafe fn $fn_name:ident
876
877		$($stuff:tt)*
878	} => {
879		$crate::chain_fns! {
880			@impl
881			$({ doctype $($doc_type)* })?
882
883			doc [Self::$fn_name]$(($($doc_link_to)+))?
884			$(#[$meta])*
885			unsafe fn $fn_name
886
887			$($stuff)*
888		}
889	};
890
891	{
892		@impl
893		$({ doctype $($doc_type:tt)* })?
894
895		$(doc [$($doc:tt)+]$(($($doc_link_to:tt)+))?)?
896		$(#[$meta:meta])*
897		fn $fn_name:ident$([$($generics:tt)*])?
898		($inner:ident $($params:tt)*)
899		$(where { $($where:tt)* })?
900		$(-> $return_type:ty)?
901		{ $($impl:tt)* }
902
903		$($stuff:tt)*
904	} => {
905		$crate::chain_fns! {
906			@helper doc
907			{
908				#[inline]
909				$(#[$meta])*
910			}
911			$(doc { [$($doc)+]$(($($doc_link_to)+))? })?
912			$(doctype { $($doc_type)* })?
913
914			item
915			pub fn $fn_name$(<$($generics)*>)?(mut self $($params)*)
916			-> $crate::chain_fns! { @helper return_type $($return_type)? }
917			$(where $($where)*)?
918			{
919				$crate::chain_fns! {
920					@helper rest
921					self
922					$inner
923					$($return_type)?
924					{ $($impl)* }
925				}
926			}
927		}
928
929		$crate::chain_fns! {
930			@impl
931			$({ doctype $($doc_type)* })?
932			$($stuff)*
933		}
934	};
935
936	{
937		@impl
938		$({ doctype $($doc_type:tt)* })?
939
940		$(doc [$($doc:tt)+]$(($($doc_link_to:tt)+))?)?
941		$(#[$meta:meta])*
942		unsafe fn $fn_name:ident$([$($generics:tt)*])?
943		($inner:ident $($params:tt)*)
944		$(where { $($where:tt)* })?
945		$(-> $return_type:ty)?
946		{ $($impl:tt)* }
947
948		$($stuff:tt)*
949	} => {
950		$crate::chain_fns! {
951			@helper doc unsafe
952			{
953				#[inline]
954				$(#[$meta])*
955			}
956			$(doc { [$($doc)+]$(($($doc_link_to)+))? })?
957			$(doctype { $($doc_type)* })?
958
959			item
960			pub unsafe fn $fn_name$(<$($generics)*>)?(mut self $($params)*)
961			-> $crate::chain_fns! { @helper return_type $($return_type)? }
962			$(where $($where)*)?
963			{
964				$crate::chain_fns! {
965					@helper rest
966					self
967					$inner
968					$($return_type)?
969					{ $($impl)* }
970				}
971			}
972		}
973
974		$crate::chain_fns! {
975			@impl
976			$({ doctype $($doc_type)* })?
977			$($stuff)*
978		}
979	};
980
981	{
982		@impl
983		$({ doctype $($doc_type:tt)* })?
984	} => {};
985
986	{
987		@helper doc $(unsafe)?
988		{ $(#[$before_meta:meta])* }
989		$(doctype { $doc_type:literal $($doc_type_link_to:literal)? })?
990		item $item:item
991	} => {
992		$(#[$before_meta])*
993		$item
994	};
995
996	{
997		@helper doc
998		{ $(#[$before_meta:meta])* }
999		doc { [$doc:literal]$(($doc_link_to:literal))? }
1000		$(doctype { $doc_type:literal $($doc_type_link_to:literal)? })?
1001		item $item:item
1002	} => {
1003		$crate::chain_fns! {
1004			@helper doc_impl
1005			{ $(#[$before_meta])* }
1006			doc { $doc }
1007			$(doc_link_to { $doc_link_to })?
1008			item $item
1009		}
1010	};
1011
1012	{
1013		@helper doc unsafe
1014		{ $(#[$before_meta:meta])* }
1015		doc { [$doc:literal]$(($doc_link_to:literal))? }
1016		$(doctype { $doc_type:literal $($doc_type_link_to:literal)? })?
1017		item $item:item
1018	} => {
1019		$crate::chain_fns! {
1020			@helper doc_impl unsafe
1021			{ $(#[$before_meta])* }
1022			doc { $doc }
1023			$(doc_link_to { $doc_link_to })?
1024			item $item
1025		}
1026	};
1027
1028	// below 2 macro arms branches things
1029	// should be identical to the 2 below
1030	// except with doc_link_to removed
1031	// (need to keep doc_type_link_to to make it trivial to invoke)
1032	{
1033		@helper doc
1034		{ $(#[$before_meta:meta])* }
1035		doc { [Self::$doc:ident] }
1036		doctype { $doc_type:literal $($doc_type_link_to:literal)? }
1037		item $item:item
1038	} => {
1039		$crate::chain_fns! {
1040			@helper doc_impl
1041			{ $(#[$before_meta])* }
1042			doc { $doc_type, "::", stringify!($doc) }
1043			$(doc_link_to { $doc_type_link_to, "::", stringify!($doc) })?
1044			item $item
1045		}
1046	};
1047
1048	{
1049		@helper doc unsafe
1050		{ $(#[$before_meta:meta])* }
1051		doc { [Self::$doc:ident] }
1052		doctype { $doc_type:literal $($doc_type_link_to:literal)? }
1053		item $item:item
1054	} => {
1055		$crate::chain_fns! {
1056			@helper doc_impl unsafe
1057			{ $(#[$before_meta])* }
1058			doc { $doc_type, "::", stringify!($doc) }
1059			$(doc_link_to { $doc_type_link_to, "::", stringify!($doc) })?
1060			item $item
1061		}
1062	};
1063
1064	// probably broken/out of date
1065	// {
1066	// 	@helper doc
1067	// 	{ $(#[$before_meta:meta])* }
1068	// 	doc { self::$doc:literal $($doc_link_to:literal)? }
1069	// 	doctype { $doc_type:literal $($doc_type_link_to:literal)? }
1070	// 	item $item:item
1071	// } => {
1072	// 	$crate::chain_fns! {
1073	// 		@helper doc_impl
1074	// 		{ $(#[$before_meta])* }
1075	// 		doc { $doc_type, "::", $doc }
1076	// 		$(doc_link_to { $doc_link_to })?
1077	// 		item $item
1078	// 	}
1079	// };
1080
1081	// probably broken/out of date
1082	// {
1083	// 	@helper doc unsafe
1084	// 	{ $(#[$before_meta:meta])* }
1085	// 	doc { self::$doc:literal $($doc_link_to:literal)? }
1086	// 	doctype { $doc_type:literal $($doc_type_link_to:literal)? }
1087	// 	item $item:item
1088	// } => {
1089	// 	$crate::chain_fns! {
1090	// 		@helper doc_impl unsafe
1091	// 		{ $(#[$before_meta])* }
1092	// 		doc { $doc_type, "::", $doc }
1093	// 		$(doc_link_to { $doc_link_to })?
1094	// 		item $item
1095	// 	}
1096	// };
1097
1098	// probably broken/out of date
1099	// {
1100	// 	@helper doc
1101	// 	{ $(#[$before_meta:meta])* }
1102	// 	doc { $doc:literal self::$doc_link_to:literal }
1103	// 	doctype { $doc_type:literal $doc_type_link_to:literal }
1104	// 	item $item:item
1105	// } => {
1106	// 	$crate::chain_fns! {
1107	// 		@helper doc_impl
1108	// 		{ $(#[$before_meta])* }
1109	// 		doc { $doc }
1110	// 		doc_link_to { $doc_type_link_to, "::", $doc_link_to }
1111	// 		item $item
1112	// 	}
1113	// };
1114
1115	// probably broken/out of date
1116	// {
1117	// 	@helper doc unsafe
1118	// 	{ $(#[$before_meta:meta])* }
1119	// 	doc { $doc:literal self::$doc_link_to:literal }
1120	// 	doctype { $doc_type:literal $doc_type_link_to:literal }
1121	// 	item $item:item
1122	// } => {
1123	// 	$crate::chain_fns! {
1124	// 		@helper doc_impl unsafe
1125	// 		{ $(#[$before_meta])* }
1126	// 		doc { $doc }
1127	// 		doc_link_to { $doc_type_link_to, "::", $doc_link_to }
1128	// 		item $item
1129	// 	}
1130	// };
1131
1132	// probably broken/out of date
1133	// {
1134	// 	@helper doc
1135	// 	{ $(#[$before_meta:meta])* }
1136	// 	doc { self::$doc:literal $(self::$doc_link_to:literal)? }
1137	// 	doctype { $doc_type:literal $($doc_type_link_to:literal)? }
1138	// 	item $item:item
1139	// } => {
1140	// 	$crate::chain_fns! {
1141	// 		@helper doc_impl
1142	// 		{ $(#[$before_meta])* }
1143	// 		doc { $doc_type, "::", $doc }
1144	// 		doc_link_to { $doc_type_link_to, "::", $doc_link_to }
1145	// 		item $item
1146	// 	}
1147	// };
1148
1149	// probably broken/out of date
1150	// {
1151	// 	@helper doc unsafe
1152	// 	{ $(#[$before_meta:meta])* }
1153	// 	doc { self::$doc:literal $(self::$doc_link_to:literal)? }
1154	// 	doctype { $doc_type:literal $($doc_type_link_to:literal)? }
1155	// 	item $item:item
1156	// } => {
1157	// 	$crate::chain_fns! {
1158	// 		@helper doc_impl unsafe
1159	// 		{ $(#[$before_meta])* }
1160	// 		doc { $doc_type, "::", $doc }
1161	// 		doc_link_to { $doc_type_link_to, "::", $doc_link_to }
1162	// 		item $item
1163	// 	}
1164	// };
1165
1166	{
1167		@helper doc_impl
1168		{ $(#[$before_meta:meta])* }
1169		doc { $($doc:tt)* }
1170		$(doc_link_to { $($doc_link_to:tt)* })?
1171		item $item:item
1172	} => {
1173		$(#[$before_meta])*
1174		#[doc = ""]
1175		#[doc = concat!(
1176			"See documentation for [`",
1177			$($doc)*,
1178			"`]",
1179			$(
1180				"(",
1181				$($doc_link_to)*,
1182				")",
1183			)?
1184			" for more details on the underlying function."
1185		)]
1186		$item
1187	};
1188
1189	{
1190		@helper doc_impl unsafe
1191		{ $(#[$before_meta:meta])* }
1192		doc { $($doc:tt)* }
1193		$(doc_link_to { $($doc_link_to:tt)* })?
1194		item $item:item
1195	} => {
1196		$(#[$before_meta])*
1197		#[doc = ""]
1198		#[doc = "# Safety"]
1199		#[doc = ""]
1200		#[doc = concat!(
1201			"You must uphold safety invariants of [`",
1202			$($doc)*,
1203			"`]",
1204			$(
1205				"(",
1206				$($doc_link_to)*,
1207				")",
1208			)?
1209			"."
1210		)]
1211		#[doc = ""]
1212		#[doc = concat!(
1213			"See documentation for [`",
1214			$($doc)*,
1215			"`]",
1216			$(
1217				"(",
1218				$($doc_link_to)*,
1219				")",
1220			)?
1221			" for more details on the underlying function."
1222		)]
1223		$item
1224	};
1225
1226	{ @helper rest $self:ident $inner:ident { $($impl:tt)*} } => {
1227		let $inner = <Self as $crate::ChainConversions>::as_inner_mut(&mut $self);
1228		let _: () = { $($impl)* };
1229		$self
1230	};
1231
1232	{ @helper rest $self:ident $inner:ident $type:ty { $($impl:tt)*} } => {
1233		// shushes the unused_mut warning
1234		// I could modify the macro more to not emit `mut self` in the parameter
1235		// if it isn't needed, but... this is simpler in code I have to type, and
1236		// compiler is surely smart enough to remove this
1237		let _ = &mut $self;
1238
1239		let $inner = $self.into_inner();
1240		let inner = { $($impl)* };
1241		$crate::Chain::from_inner(inner)
1242	};
1243
1244	{ @helper return_type } => { Self };
1245	{ @helper return_type $type:ty } => { $crate::Chain<$type> };
1246
1247	{ $($stuff:tt)* } => {
1248		$crate::chain_fns! { @head $($stuff)* }
1249	};
1250}
1251use chain_fns;
1252
1253#[allow(
1254	unused_imports,
1255	reason = "internal prelude"
1256)]
1257#[expect(
1258	clippy::allow_attributes,
1259	reason = "internal prelude"
1260)]
1261mod prelude_internal {
1262	pub(crate) use crate::{
1263		Chain,
1264		ChainConversions,
1265		Output,
1266		chain_fns,
1267		impl_chain_conversions
1268	};
1269}
1270
1271/// notouchie
1272mod sealed {
1273	/// notouchie
1274	pub mod output {
1275		/// notouchie
1276		pub trait Sealed<T> {}
1277	}
1278
1279	/// notouchie
1280	pub mod chain_conversions {
1281		/// notouchie
1282		pub trait Sealed {}
1283	}
1284}