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;