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 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
//! Traits for assembling and disassembling items. use fehler::throws; /// Describes a failure to assemble a composite from a sequence of parts. #[derive(Debug, PartialEq)] pub enum AssembleFailure<E> { /// There were not enough parts. Incomplete, /// There was an error with the parts. Error(E), } /// Converts an `E` into an `AssembleFailure`. impl<E> From<E> for AssembleFailure<E> { #[inline] fn from(error: E) -> Self { Self::Error(error) } } /// Specifies the assembly of `Self` from a sequence of `P`s. pub trait AssembleFrom<P> where Self: Sized, { /// Describes an error with the parts. /// /// This SHALL describe all cases that prevent a successful assembly other than the case where more parts are needed. type Error; /// Assembles `parts` into a `Self`. /// /// If assembly is successful, all items used in the assembly SHALL be removed from `parts`. /// /// # Errors /// /// If assembly fails, the cause of the failure SHALL be thrown and `parts` SHALL NOT be modified. #[throws(AssembleFailure<Self::Error>)] fn assemble_from(parts: &mut Vec<P>) -> Self; } /// Specifies the assembly of `C` from a sequence of `Self`s. pub trait AssembleInto<C> where Self: Sized, { /// Describes an error with the parts. /// /// This SHALL describe all cases that prevent a successful assembly other than the case where more parts are needed. type Error; /// Assembles `parts` into a `C`. /// /// If assembly is successful, all items used in the assembly SHALL be removed from `parts`. /// /// # Errors /// /// If assembly fails, the cause of the failure SHALL be thrown and `parts` SHALL NOT be modified. #[throws(AssembleFailure<Self::Error>)] fn assemble_into(parts: &mut Vec<Self>) -> C; } /// For every `C` that implements `AssembleFrom<P>`, `P` SHALL implement `AssembleInto<S>`. impl<P, C> AssembleInto<C> for P where C: AssembleFrom<P>, { type Error = <C as AssembleFrom<Self>>::Error; #[inline] #[throws(AssembleFailure<Self::Error>)] fn assemble_into(parts: &mut Vec<Self>) -> C { C::assemble_from(parts)? } } /// Disassembles a `C` into a sequence of `Self`s. pub trait DisassembleFrom<C> where Self: Sized, { /// Describes an error that prevents disassembly. type Error; /// Disassembles `composite` into a sequence of `Self`s. /// /// # Errors /// /// If disassembly fails, the cause of the failure SHALL be thrown. #[throws(Self::Error)] fn disassemble_from(composite: C) -> Vec<Self>; } /// Disassembles `Self` into a sequence of `P`s. pub trait DisassembleInto<P> { /// Describes an error that prevents disassembly. type Error; /// Disassembles `self` into a sequence of parts. /// /// # Errors /// /// If disassembly fails, the cause of the failure SHALL be thrown. #[throws(Self::Error)] fn disassemble_into(self) -> Vec<P>; } /// For every `P` that implements `DisassembleFrom<C>`, `C` SHALL implement `DisassembleInto<P>`. impl<P, C> DisassembleInto<P> for C where P: DisassembleFrom<C>, { type Error = <P as DisassembleFrom<Self>>::Error; #[inline] #[throws(Self::Error)] fn disassemble_into(self) -> Vec<P> { P::disassemble_from(self)? } }