placid/
init.rs

1//! Traits and types for initializing places.
2//!
3//! This module defines the [`Init`] and [`InitPin`] traits, which provide
4//! abstractions for initializing uninitialized memory places. It also includes
5//! various initializers and combinators for building complex initialization
6//! patterns.
7
8use core::{convert::Infallible, fmt, pin::Pin};
9
10use crate::{
11    owned::Own,
12    pin::{DropSlot, POwn},
13    uninit::Uninit,
14};
15
16/// A marker trait for initializers.
17///
18/// This trait itself does not provide any methods, but serves as a common
19/// supertrait for all initializer traits. It allows for generic programming
20/// over different kinds of initializers.
21#[diagnostic::on_unimplemented(
22    message = "`{Self}` is not an initializer",
23    label = "`{Self}` is not an initializer"
24)]
25pub trait Initializer: Sized {
26    /// The error type that can occur during initialization.
27    type Error;
28
29    /// Maps the error type of the initializer using a closure.
30    ///
31    /// # Examples
32    ///
33    /// ```rust
34    /// use placid::prelude::*;
35    ///
36    /// let mut uninit = uninit!(i32);
37    /// let res = uninit.try_write(
38    ///     init::try_with(|| -> Result<_, &str> { Err("initialization failed") })
39    ///         .map_err(|e| format!("Error occurred: {}", e))
40    /// );
41    /// assert!(res.is_err());
42    /// assert_eq!(
43    ///     res.err().unwrap().error,
44    ///     "Error occurred: initialization failed"
45    /// );
46    /// ```
47    #[inline]
48    fn map_err<F, E2>(self, f: F) -> MapErr<Self, F>
49    where
50        F: FnOnce(Self::Error) -> E2,
51    {
52        map_err(self, f)
53    }
54
55    /// Adapts an infallible initializer to have a different error type.
56    ///
57    /// Since the initializer cannot fail, the provided closure will never be
58    /// called.
59    ///
60    /// # Examples
61    ///
62    /// ```rust
63    /// use placid::prelude::*;
64    /// use std::num::TryFromIntError;
65    ///
66    /// let owned: Own<u32> = own!(init::value(100u32).adapt_err::<TryFromIntError>());
67    /// assert_eq!(*owned, 100);
68    /// ```
69    #[inline]
70    fn adapt_err<E2>(self) -> MapErr<Self, impl FnOnce(Self::Error) -> E2>
71    where
72        Self: Initializer<Error = Infallible>,
73    {
74        adapt_err(self)
75    }
76}
77
78/// An error that occurs during initialization of a place.
79#[derive(thiserror::Error)]
80#[error("failed to initialize in pinned place: {error}")]
81pub struct InitPinError<'a, 'b, T: ?Sized, E> {
82    /// The error that occurred during initialization.
83    #[source]
84    pub error: E,
85    /// The place that failed to be initialized.
86    pub place: Uninit<'a, T>,
87    /// The drop slot associated with the initialized place.
88    pub slot: DropSlot<'a, 'b, T>,
89}
90
91impl<'a, 'b, T: ?Sized, E> InitPinError<'a, 'b, T, E> {
92    /// Creates a new `InitPinError`.
93    #[inline]
94    pub const fn new(error: E, place: Uninit<'a, T>, slot: DropSlot<'a, 'b, T>) -> Self {
95        InitPinError { error, place, slot }
96    }
97
98    /// Maps the error contained in this `InitPinError` to a different error
99    /// type.
100    #[inline]
101    pub fn map<F, E2>(self, f: F) -> InitPinError<'a, 'b, T, E2>
102    where
103        F: FnOnce(E) -> E2,
104    {
105        InitPinError {
106            error: f(self.error),
107            place: self.place,
108            slot: self.slot,
109        }
110    }
111}
112
113impl<'a, 'b, T: ?Sized, E: fmt::Debug> fmt::Debug for InitPinError<'a, 'b, T, E> {
114    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115        f.debug_struct("Error")
116            .field("error", &self.error)
117            .field("place", &self.place)
118            .field("slot", &self.slot)
119            .finish()
120    }
121}
122
123/// The result type for [pinned initialization].
124///
125/// [pinned initialization]: crate::init::InitPin::init_pin
126pub type InitPinResult<'a, 'b, T, E> = Result<POwn<'b, T>, InitPinError<'a, 'b, T, E>>;
127
128/// A trait for initializing a place with a pinned value.
129///
130/// This trait is used to abstract over the different ways a place can be
131/// initialized. See the implementors for more details.
132///
133/// # Safety
134///
135/// This trait is itself safe to implement. However, care must be taken when
136/// implementing the `init_pin` method to ensure the pinning guarantees if
137/// hand-written unsafe code is involved.
138///
139/// An important aspect worth noting is that the `init_pin` method **cannot
140/// leave a partially-pin-initialized state** in the provided `place` even if
141/// initialization fails. This is crucial to maintain the safety guarantees of
142/// the pinning abstraction.
143///
144/// For example, when pin-initializing a struct:
145///
146/// ```ignore
147/// #[pin]
148/// struct A {
149///     #[pin]
150///     b: B,
151///     c: C,
152/// }
153/// ```
154///
155/// If the initialization of field `b` succeeds before the initialization of
156/// field `c` fails, **`b` must be dropped before returning the error or
157/// resuming the panic**. On the other hand, if the initialization of `b` fails
158/// after `c` is initialized, no cleanup is necessary since `c` is not pinned
159/// and can be safely `mem::forget`ed.
160#[diagnostic::on_unimplemented(
161    message = "`{Self}` is not a pin-initializer for places of type `{T}`",
162    label = "`{Self}` is not a pin-initializer for type `{T}`"
163)]
164pub trait InitPin<T: ?Sized>: Initializer {
165    /// Initializes a place with a pinned value.
166    ///
167    /// This method performs the actual initialization of an uninitialized
168    /// place, creating a pinned reference to the initialized value. It
169    /// requires both an uninitialized place and a drop slot to manage the
170    /// value's lifetime.
171    ///
172    /// # Arguments
173    ///
174    /// * `place` - The uninitialized place to initialize
175    /// * `slot` - The drop slot for managing the pinned value's lifetime
176    ///
177    /// # Returns
178    ///
179    /// Returns a [pinned owned reference] on success, or an [`InitPinError`]
180    /// containing the error and the failed place.
181    ///
182    /// [pinned owned reference]: crate::pin::POwn
183    fn init_pin<'a, 'b>(
184        self,
185        place: Uninit<'a, T>,
186        slot: DropSlot<'a, 'b, T>,
187    ) -> InitPinResult<'a, 'b, T, Self::Error>;
188
189    /// Chains a closure to execute after successful initialization with a
190    /// pinned reference.
191    ///
192    /// This method allows you to perform additional setup on the initialized
193    /// value while maintaining its pinned status. The closure receives a
194    /// mutable pinned reference to the newly initialized value.
195    ///
196    /// # Examples
197    ///
198    /// ```rust
199    /// use placid::prelude::*;
200    /// use core::pin::Pin;
201    ///
202    /// let owned: POwn<Vec<_>> = pown!(
203    ///     init::value(vec![1, 2, 3]).and_pin(|mut v| v.as_mut().push(4))
204    /// );
205    /// assert_eq!(*owned, [1, 2, 3, 4]);
206    /// ```
207    #[inline]
208    fn and_pin<F: FnOnce(Pin<&mut T>)>(self, f: F) -> AndPin<Self, F> {
209        and_pin(self, f)
210    }
211
212    /// Provides a fallback initializer if this one fails.
213    ///
214    /// If initialization fails, the `other` initializer will be attempted
215    /// instead. The `other` initializer must produce the same target type
216    /// and have an error that can be converted to this initializer's error
217    /// type.
218    ///
219    /// # Examples
220    ///
221    /// ```rust
222    /// use placid::prelude::*;
223    ///
224    /// let owned: Own<u32> = own!(init::value(10u32).or(20u32));
225    /// assert_eq!(*owned, 10);
226    ///
227    /// let failed: Own<u32> = own!(init::try_with(|| u32::try_from(-1i32)).or(30u32));
228    /// assert_eq!(*failed, 30);
229    /// ```
230    #[inline]
231    fn or<M, I2>(self, other: I2) -> Or<Self, I2, M>
232    where
233        I2: IntoInitPin<T, M, Error: Into<Self::Error>>,
234    {
235        or(self, other)
236    }
237
238    /// Provides a fallback initializer based on the error from this one.
239    ///
240    /// If initialization fails, the closure `f` is called with the error, and
241    /// the returned initializer is used instead. This allows for
242    /// error-dependent recovery.
243    ///
244    /// # Examples
245    ///
246    /// ```rust
247    /// use placid::prelude::*;
248    ///
249    /// let owned: Own<u32> = own!(init::try_with(|| u32::try_from(-1i32)).or_else(|err| {
250    ///     println!("Initialization failed with error: {}", err);
251    ///     init::value(42u32)
252    /// }));
253    /// assert_eq!(*owned, 42);
254    /// ```
255    #[inline]
256    fn or_else<F, I2>(self, f: F) -> OrElse<Self, F>
257    where
258        F: FnOnce(Self::Error) -> I2,
259        I2: InitPin<T, Error: Into<Self::Error>>,
260    {
261        or_else(self, f)
262    }
263
264    /// Provides a fallback initializer if the primary one fails. The fallback
265    /// initializer must be infallible.
266    ///
267    /// # Examples
268    ///
269    /// ```rust
270    /// use placid::prelude::*;
271    ///
272    /// let owned = own!(init::value(10u32).unwrap_or(20u32));
273    /// assert_eq!(*owned, 10);
274    ///
275    /// let failed = own!(
276    ///     init::try_with(|| u32::try_from(-1i32)).unwrap_or(30u32)
277    /// );
278    /// assert_eq!(*failed, 30);
279    /// ```
280    #[inline]
281    fn unwrap_or<M, I2>(self, other: I2) -> UnwrapOr<Self, I2, M>
282    where
283        I2: IntoInitPin<T, M, Error = Infallible>,
284    {
285        unwrap_or(self, other)
286    }
287
288    /// Provides a fallback initializer computed from the error of the primary
289    /// one. The fallback initializer must be infallible.
290    ///
291    /// # Examples
292    ///
293    /// ```rust
294    /// use placid::prelude::*;
295    ///
296    /// let owned = own!(
297    ///     init::try_with(|| u32::try_from(-1i32))
298    ///         .unwrap_or_else(|err| {
299    ///             println!("Initialization failed with error: {}", err);
300    ///             init::value(42u32)
301    ///         })
302    /// );
303    /// assert_eq!(*owned, 42);
304    /// ```
305    #[inline]
306    fn unwrap_or_else<F, I2>(self, f: F) -> UnwrapOrElse<Self, F>
307    where
308        F: FnOnce(Self::Error) -> I2,
309        I2: InitPin<T, Error = Infallible>,
310    {
311        unwrap_or_else(self, f)
312    }
313}
314
315/// An error that occurs during initialization of a place.
316#[derive(thiserror::Error)]
317#[error("failed to initialize in place: {error}")]
318pub struct InitError<'a, T: ?Sized, E> {
319    /// The error that occurred during initialization.
320    #[source]
321    pub error: E,
322    /// The place that failed to be initialized.
323    pub place: Uninit<'a, T>,
324}
325
326impl<'a, T: ?Sized, E> InitError<'a, T, E> {
327    /// Creates a new `InitError`.
328    #[inline]
329    pub const fn new(error: E, place: Uninit<'a, T>) -> Self {
330        InitError { error, place }
331    }
332
333    /// Converts this error into an `InitPinError` by adding a drop slot.
334    #[inline]
335    pub fn into_pin<'b>(self, slot: DropSlot<'a, 'b, T>) -> InitPinError<'a, 'b, T, E> {
336        InitPinError {
337            error: self.error,
338            place: self.place,
339            slot,
340        }
341    }
342
343    /// Maps the error contained in this `InitError` to a different error type.
344    #[inline]
345    pub fn map<F, E2>(self, f: F) -> InitError<'a, T, E2>
346    where
347        F: FnOnce(E) -> E2,
348    {
349        InitError {
350            error: f(self.error),
351            place: self.place,
352        }
353    }
354}
355
356impl<'a, 'b, T: ?Sized, E> From<InitPinError<'a, 'b, T, E>> for InitError<'a, T, E> {
357    #[inline]
358    fn from(err: InitPinError<'a, 'b, T, E>) -> Self {
359        InitError {
360            error: err.error,
361            place: err.place,
362        }
363    }
364}
365
366impl<'a, T: ?Sized, E: fmt::Debug> fmt::Debug for InitError<'a, T, E> {
367    #[inline]
368    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
369        f.debug_struct("Error")
370            .field("error", &self.error)
371            .field("place", &self.place)
372            .finish()
373    }
374}
375
376/// The result type for [initialization].
377///
378/// [initialization]: crate::init::Init::init
379pub type InitResult<'a, T, E> = Result<Own<'a, T>, InitError<'a, T, E>>;
380
381/// A trait for initializing a place with a value.
382///
383/// This trait is used to abstract over the different ways a place can be
384/// initialized. See the implementors for more details.
385///
386/// # Safety
387///
388/// Unlike [the pinning variant](crate::init::InitPin), this trait does not have
389/// the same restrictions regarding partially-initialized states. This is
390/// because the values initialized through this trait are not pinned, and thus
391/// do not have the same safety guarantees that pinned values require.
392#[diagnostic::on_unimplemented(
393    message = "`{Self}` is not an initializer for places of type `{T}`",
394    label = "`{Self}` is not an initializer for type `{T}`"
395)]
396pub trait Init<T: ?Sized>: InitPin<T> {
397    /// Initializes a place with a value.
398    ///
399    /// This method performs the actual initialization of an uninitialized
400    /// place, creating an owned reference to the initialized value. Unlike
401    /// `init_pin`, this does not pin the value.
402    ///
403    /// # Arguments
404    ///
405    /// * `place` - The uninitialized place to initialize
406    ///
407    /// # Returns
408    ///
409    /// Returns an [owned reference] on success, or an [`InitError`]
410    /// containing the error and the failed place.
411    ///
412    /// [owned reference]: crate::owned::Own
413    fn init(self, place: Uninit<'_, T>) -> InitResult<'_, T, Self::Error>;
414
415    /// Chains a closure to execute after successful initialization.
416    ///
417    /// This method allows you to perform additional setup on the initialized
418    /// value. The closure receives a mutable reference to the newly
419    /// initialized value.
420    ///
421    /// # Examples
422    ///
423    /// ```rust
424    /// use placid::prelude::*;
425    ///
426    /// let owned: Own<Vec<_>> = own!(init::value(vec![1, 2, 3]).and(|v| v.push(4)));
427    /// assert_eq!(*owned, vec![1, 2, 3, 4]);
428    /// ```
429    #[inline]
430    fn and<F: FnOnce(&mut T)>(self, f: F) -> And<Self, F> {
431        and(self, f)
432    }
433}
434
435/// A trait for converting a value into a pin-initializer for type `T`.
436///
437/// This trait is used to allow types to be directly used as initializers
438/// without needing to wrap them in a specific initializer factory function.
439///
440/// There does not exist a trait called `IntoInitializer`, which seems to be a
441/// natural extension for the `Initializer`, `InitPin`, and `Init` subtrait
442/// chain. This is because `Marker` and the target type `T` cannot be separated
443/// for correct type inference.
444#[diagnostic::on_unimplemented(
445    message = "`{Self}` is not a pin-initializer for places of type `{T}`",
446    label = "`{Self}` is not a pin-initializer for type `{T}`"
447)]
448pub trait IntoInitPin<T: ?Sized, Marker = ()>: Sized {
449    /// Which kind of initializer this converts into?
450    type Init: InitPin<T, Error = Self::Error>;
451    /// The error type that can occur during initialization.
452    type Error;
453
454    /// Creates an initializer from this value.
455    fn into_init(self) -> Self::Init;
456}
457
458impl<T: ?Sized, I: InitPin<T>> IntoInitPin<T> for I {
459    type Init = I;
460    type Error = I::Error;
461
462    #[inline]
463    fn into_init(self) -> Self::Init {
464        self
465    }
466}
467
468/// A trait for converting a value into an initializer for type `T`.
469///
470/// This trait is used to allow types to be directly used as initializers
471/// without needing to wrap them in a specific initializer factory function.
472///
473/// This trait is automatically implemented for any type that implements
474/// [`IntoInitPin`] with an initializer that also implements [`Init`].
475#[diagnostic::on_unimplemented(
476    message = "`{Self}` is not an initializer for places of type `{T}`",
477    label = "`{Self}` is not an initializer for type `{T}`"
478)]
479pub trait IntoInit<T: ?Sized, Marker = ()>:
480    IntoInitPin<T, Marker, Init: Init<T, Error = Self::Error>>
481{
482}
483impl<T, Marker, I> IntoInit<T, Marker> for I
484where
485    T: ?Sized,
486    I: IntoInitPin<T, Marker, Init: Init<T, Error = Self::Error>>,
487{
488}
489
490// Factory functions & adapters
491
492mod and;
493pub use self::and::{And, AndPin, and, and_pin};
494
495mod or;
496pub use self::or::{
497    MapErr, Or, OrElse, UnwrapOr, UnwrapOrElse, adapt_err, map_err, or, or_else, unwrap_or,
498    unwrap_or_else,
499};
500
501mod raw;
502pub use self::raw::{Raw, RawPin, TryRaw, TryRawPin, raw, raw_pin, try_raw, try_raw_pin};
503
504mod slice;
505pub use self::slice::{
506    Repeat, RepeatWith, Slice, SliceError, Str, repeat, repeat_with, slice, str,
507};
508
509mod value;
510pub use self::value::{TryWith, Value, With, try_with, value, with};
511
512// Implemetations for the standard library types
513
514mod imp;
515
516// Structural initializers
517
518/// Types that can be structurally initialized in a pinned place.
519///
520/// This trait is automatically implemented for types that derive [`InitPin`].
521/// It provides a method to structurally initialize the type in a pinned
522/// context.
523///
524/// Users should not implement this trait manually. It is intended to be
525/// automatically derived to ensure correct behavior.
526///
527/// [`InitPin`]: macro@InitPin
528#[diagnostic::on_unimplemented(
529    message = "`{Self}` cannot be structurally pin-initialized",
530    label = "`{Self}` cannot be structurally pin-initialized",
531    note = "`#[derive(InitPin)]` to enable structural pin-initialization for this type"
532)]
533pub trait StructuralInitPin<'b> {
534    #[doc(hidden)]
535    type __BuilderInitPin<'a: 'b>
536    where
537        Self: 'a;
538
539    #[doc(hidden)]
540    fn __builder_init_pin<'a>(
541        place: Uninit<'a, Self>,
542        slot: DropSlot<'a, 'b, Self>,
543    ) -> Self::__BuilderInitPin<'a>
544    where
545        Self: 'a;
546}
547
548/// Types that can be structurally initialized in a place.
549///
550/// This trait is automatically implemented for types that derive [`Init`]. It
551/// provides a method to structurally initialize the type in a non-pinned
552/// context.
553///
554/// [`Init`]: macro@Init
555#[diagnostic::on_unimplemented(
556    message = "`{Self}` cannot be structurally initialized",
557    label = "`{Self}` cannot be structurally initialized",
558    note = "`#[derive(Init)]` to enable structural initialization for this type"
559)]
560pub trait StructuralInit<'b>: StructuralInitPin<'b> {
561    #[doc(hidden)]
562    type __BuilderInit;
563
564    #[doc(hidden)]
565    fn __builder_init(place: Uninit<'b, Self>) -> Self::__BuilderInit;
566}
567
568/// Marks a type as structurally initializable.
569///
570/// It provides a method to structurally initialize the type in an unpinned
571/// context. The initializer can be created by the [`macro@init!`] macro.
572///
573/// It also implements [`StructuralInit`] for the derived type.
574///
575/// [`macro@Init`] and [`macro@InitPin`] are mutually exclusive; a type can
576/// derive either one or the other, depending on whether it supports unpinned or
577/// pinned initialization.
578///
579/// Types that derive `Init` automatically implement [`StructuralInit`]
580/// and [`StructuralInitPin`] (i.e., **auto-derives [`macro@InitPin`]
581/// without structural field pinning**. Please use it carefully with other `pin`
582/// based crates, such as `pin-projection`).
583///
584/// # Examples
585///
586/// A simple usage example (although not practical):
587///
588/// ```rust
589/// use placid::prelude::*;
590///
591/// #[derive(Init)]
592/// struct Point {
593///     x: i32,
594///     y: i32,
595/// }
596///
597/// let owned = own!(init!(Point { x: 10, y: 20 }));
598/// assert_eq!(owned.x, 10);
599/// assert_eq!(owned.y, 20);
600/// ```
601///
602/// For more complex usage, see the [crate-level documentation](crate) for
603/// more information.
604pub use placid_macro::Init;
605/// Marks a type as structurally pin-initializable.
606///
607/// It provides a method to structurally initialize the type in a pinned
608/// context. The initializer can be created by the [`macro@init!`] macro.
609///
610/// It also implements [`StructuralInitPin`] for the derived type.
611///
612/// [`macro@Init`] and [`macro@InitPin`] are mutually exclusive; a type can
613/// derive either one or the other, depending on whether it supports unpinned or
614/// pinned initialization.
615///
616/// Types that derive `InitPin` automatically implement
617/// [`StructuralInitPin`].
618///
619/// # Examples
620///
621/// A simple usage example (although not practical):
622///
623/// ```rust
624/// use placid::prelude::*;
625/// use std::{marker::PhantomPinned, pin::Pin};
626///
627/// #[derive(InitPin, Debug)]
628/// struct Pinned {
629///     ptr: *const Pinned,
630///     marker: PhantomPinned,
631/// }
632///
633/// let owned: POwn<Pinned> = pown!(init_pin!(Pinned {
634///     ptr: std::ptr::null(),
635///     marker: PhantomPinned,
636/// })
637/// .and_pin(|this| unsafe {
638///     // SAFETY: We are initializing the self-referential pointer.
639///     let this = Pin::into_inner_unchecked(this);
640///     this.ptr = std::ptr::from_ref(this);
641/// }));
642///
643/// assert_eq!(owned.ptr, &*owned);
644/// ```
645///
646/// For more complex usage, see the [crate-level documentation](crate) for
647/// more information.
648pub use placid_macro::InitPin;
649/// Creates an initializer for a [structurally initialized] type.
650///
651/// # Syntax
652///
653/// The macro accepts standard Rust expressions, but it will expand those which
654/// match the following pattern into structured initializers:
655///
656/// ```ignore
657/// init!(
658///     // Specify an optional error type for
659///     // sub-initializers to convert into.
660///     // Otherwise, no conversion is performed.
661///     #[err_into(ErrorType)]
662///     TypeName {
663///         field: initializer,
664///         // Sub-initializers can also have their own error types.
665///         #[err_into(SubErrorType)]
666///         nested: NestedType {
667///             subfield: initializer,
668///             ...
669///         }
670///         // Mark `err_into` without an argument to indicate
671///         // automatic `Into::into`.
672///         #[err_into]
673///         nested2: Tuple(initializer, ...),
674///         ...
675///     }
676/// )
677/// ```
678///
679/// Expressions that do not match the above pattern are treated as-is.
680///
681/// # Examples
682///
683/// A simple usage example (although not practical):
684///
685/// ```rust
686/// use placid::prelude::*;
687///
688/// #[derive(Init)]
689/// struct Point {
690///     x: i32,
691///     y: i32,
692/// }
693///
694/// let owned = own!(init!(Point { x: 10, y: 20 }));
695/// assert_eq!(owned.x, 10);
696/// assert_eq!(owned.y, 20);
697/// ```
698///
699/// For more complex usage, see the [crate-level documentation](crate) for more
700/// information.
701///
702/// [structurally initialized]: macro@crate::Init
703pub use placid_macro::init;
704/// Creates a pin-initializer for a [structurally pin-initialized] type.
705///
706/// # Syntax
707///
708/// The macro accepts standard Rust expressions, but it will expand those which
709/// match the following pattern into structured initializers:
710///
711/// ```ignore
712/// init_pin!(
713///     // Specify an optional error type for
714///     // sub-initializers to convert into.
715///     // Otherwise, no conversion is performed.
716///     #[err_into(ErrorType)]
717///     TypeName {
718///         field: initializer,
719///         // Sub-initializers can also have their own error types.
720///         #[err_into(SubErrorType)]
721///         nested: NestedType {
722///             subfield: initializer,
723///             ...
724///         }
725///         // Pinned fields must be marked with `#[pin]`.
726///         #[pin]
727///         // Mark `err_into` without an argument to indicate
728///         // automatic `Into::into`.
729///         #[err_into]
730///         nested2: Tuple(initializer, ...),
731///         ...
732///     }
733/// )
734/// ```
735///
736/// Expressions that do not match the above pattern are treated as-is.
737///
738/// # Examples
739///
740/// A simple usage example (although not practical):
741///
742/// ```rust
743/// use placid::prelude::*;
744///
745/// #[derive(InitPin)]
746/// struct Point {
747///     x: i32,
748///     y: i32,
749/// }
750///
751/// let owned = pown!(init_pin!(Point { x: 10, y: 20 }));
752/// assert_eq!(owned.x, 10);
753/// assert_eq!(owned.y, 20);
754/// ```
755///
756/// For more complex usage, see the [crate-level documentation](crate) for more
757/// information.
758///
759/// [structurally pin-initialized]: macro@crate::InitPin
760pub use placid_macro::init_pin;