1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
/// A trait for creating a default instance of a type, which is not **necessarily useful**.
///
/// The difference of `PseudoDefault` from `Default` is the relaxed expectation of the created instance to be useful.
///
/// The main use case of the trait is when we need to create a cheap instance of a type without any arguments to throw away.
/// This sounds exactly the same as the `Default`s definition.
/// However, the instance created by `pseudo_default` does not need to be a decent one, it is totally fine if it is useless.
///
/// We would most possibly need such an instance when we need to swap it with another instance or fill a gap in a collection.
/// `PseudoDefault` allows us to achieve this without requiring to use unsafe code and leaving the memory location uninitialized.
///
/// # Example
///
/// Consider the following fictional type `Share` which divides a whole into pieces.
/// Without providing the `number_of_shares`, this type is meaningless; i.e., we cannot justify implementing `Default`.
/// However, if we need to be able to create dummy Share's, we can simply use `pseudo_default`.
/// The created share will be useless; however, a valid and safe `Share` instance.
///
/// ```rust
/// use orx_pseudo_default::PseudoDefault;
///
/// struct Share {
/// number_of_shares: std::num::NonZeroUsize,
/// }
///
/// impl Share {
/// fn share_size(&self, whole_amount: usize) -> usize {
/// whole_amount / self.number_of_shares
/// }
/// }
///
/// impl PseudoDefault for Share {
/// fn pseudo_default() -> Self {
/// Self {
/// number_of_shares: std::num::NonZeroUsize::new(1).unwrap(),
/// }
/// }
/// }
/// ```
pub trait PseudoDefault {
/// A trait for creating a default instance of a type, which is not **necessarily useful**.
///
/// The difference of `PseudoDefault` from `Default` is the relaxed expectation of the created instance to be useful.
///
/// The main use case of the trait is when we need to create a cheap instance of a type without any arguments to throw away.
/// This sounds exactly the same as the `Default`s definition.
/// However, the instance created by `pseudo_default` does not need to be a decent one, it is totally fine if it is useless.
///
/// We would most possibly need such an instance when we need to swap it with another instance or fill a gap in a collection.
/// `PseudoDefault` allows us to achieve this without requiring to use unsafe code and leaving the memory location uninitialized.
///
/// # Example
///
/// Consider the following fictional type `Share` which divides a whole into pieces.
/// Without providing the `number_of_shares`, this type is meaningless; i.e., we cannot justify implementing `Default`.
/// However, if we need to be able to create dummy Share's, we can simply use `pseudo_default`.
/// The created share will be useless; however, a valid and safe `Share` instance.
///
/// ```rust
/// use orx_pseudo_default::PseudoDefault;
///
/// struct Share {
/// number_of_shares: std::num::NonZeroUsize,
/// }
///
/// impl Share {
/// fn share_size(&self, whole_amount: usize) -> usize {
/// whole_amount / self.number_of_shares
/// }
/// }
///
/// impl PseudoDefault for Share {
/// fn pseudo_default() -> Self {
/// Self {
/// number_of_shares: std::num::NonZeroUsize::new(1).unwrap(),
/// }
/// }
/// }
/// ```
fn pseudo_default() -> Self;
}