11//! Core functionality.
22
3- use core:: { fmt, marker:: PhantomData , ops:: Deref } ;
3+ use core:: {
4+ cmp:: Ordering ,
5+ fmt,
6+ hash:: { Hash , Hasher } ,
7+ marker:: PhantomData ,
8+ ops:: Deref ,
9+ } ;
410
511#[ cfg( feature = "serde" ) ]
612use serde:: { Deserialize , Deserializer , Serialize , Serializer , de} ;
@@ -79,19 +85,100 @@ impl<T: ?Sized, P: Predicate<T> + ?Sized> fmt::Display for Expected<T, P> {
7985///
8086/// Values of this type are guaranteed to contain values of type `T`
8187/// that satisfy the predicate `P`.
82- #[ derive( Debug , Clone , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
8388pub struct Refinement < T , P : Predicate < T > + ?Sized , C : TypeStr + ?Sized = NoContext > {
8489 value : T ,
8590 predicate : PhantomData < P > ,
8691 context : PhantomData < C > ,
8792}
8893
94+ impl < T : fmt:: Debug , P : Predicate < T > + ?Sized , C : TypeStr + ?Sized > fmt:: Debug
95+ for Refinement < T , P , C >
96+ {
97+ fn fmt ( & self , formatter : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
98+ self . get ( ) . fmt ( formatter)
99+ }
100+ }
101+
102+ impl < T : fmt:: Display , P : Predicate < T > + ?Sized , C : TypeStr + ?Sized > fmt:: Display
103+ for Refinement < T , P , C >
104+ {
105+ fn fmt ( & self , formatter : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
106+ self . get ( ) . fmt ( formatter)
107+ }
108+ }
109+
110+ impl < T : Clone , P : Predicate < T > + ?Sized , C : TypeStr + ?Sized > Clone for Refinement < T , P , C > {
111+ fn clone ( & self ) -> Self {
112+ unsafe { Self :: unchecked ( self . get ( ) . clone ( ) ) }
113+ }
114+ }
115+
116+ impl < T : Copy , P : Predicate < T > + ?Sized , C : TypeStr + ?Sized > Copy for Refinement < T , P , C > { }
117+
118+ impl < T : PartialEq , P : Predicate < T > + ?Sized , C : TypeStr + ?Sized > PartialEq
119+ for Refinement < T , P , C >
120+ {
121+ fn eq ( & self , other : & Self ) -> bool {
122+ self . get ( ) . eq ( other. get ( ) )
123+ }
124+ }
125+
126+ impl < T : Eq , P : Predicate < T > + ?Sized , C : TypeStr + ?Sized > Eq for Refinement < T , P , C > { }
127+
128+ impl < T : PartialOrd , P : Predicate < T > + ?Sized , C : TypeStr + ?Sized > PartialOrd
129+ for Refinement < T , P , C >
130+ {
131+ fn partial_cmp ( & self , other : & Self ) -> Option < Ordering > {
132+ self . get ( ) . partial_cmp ( other. get ( ) )
133+ }
134+ }
135+
136+ impl < T : Ord , P : Predicate < T > + ?Sized , C : TypeStr + ?Sized > Ord for Refinement < T , P , C > {
137+ fn cmp ( & self , other : & Self ) -> Ordering {
138+ self . get ( ) . cmp ( other. get ( ) )
139+ }
140+ }
141+
142+ impl < T : Hash , P : Predicate < T > + ?Sized , C : TypeStr + ?Sized > Hash for Refinement < T , P , C > {
143+ fn hash < H : Hasher > ( & self , hasher : & mut H ) {
144+ self . get ( ) . hash ( hasher) ;
145+ }
146+ }
147+
148+ impl < T , P : Predicate < T > + ?Sized , C : TypeStr + ?Sized > Deref for Refinement < T , P , C > {
149+ type Target = T ;
150+
151+ fn deref ( & self ) -> & Self :: Target {
152+ self . get ( )
153+ }
154+ }
155+
156+ impl < T : Default , P : Predicate < T > + ?Sized , C : TypeStr + ?Sized > Refinement < T , P , C > {
157+ /// Refines the default value of type `T`.
158+ ///
159+ /// # Errors
160+ ///
161+ /// Returns [`struct@Error`] if the default value does not satisfy the predicate.
162+ pub fn try_default ( ) -> Result < Self , Error < T , P , C > > {
163+ Self :: refine ( T :: default ( ) )
164+ }
165+
166+ /// Constructs [`Self`] without checking the default value.
167+ ///
168+ /// # Safety
169+ ///
170+ /// The caller must ensure that the default value satisfies the predicate.
171+ pub unsafe fn unchecked_default ( ) -> Self {
172+ unsafe { Self :: unchecked ( T :: default ( ) ) }
173+ }
174+ }
175+
89176#[ cfg( feature = "serde" ) ]
90177impl < T : Serialize , P : Predicate < T > + ?Sized , C : TypeStr + ?Sized > Serialize
91178 for Refinement < T , P , C >
92179{
93180 fn serialize < S : Serializer > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error > {
94- self . value . serialize ( serializer)
181+ self . get ( ) . serialize ( serializer)
95182 }
96183}
97184
@@ -128,7 +215,7 @@ impl<T, P: Predicate<T> + ?Sized, C: TypeStr + ?Sized> Refinement<T, P, C> {
128215/// This error is constructed from the value that failed to satisfy the predicate
129216/// and the error produced by the predicate.
130217#[ derive( Debug , Error ) ]
131- #[ error( "expected {expected} [{context}]" , expected = P :: expected( ) , context = C :: VALUE ) ]
218+ #[ error( "expected {expected} [{context}]" , expected = P :: expected( ) , context = Self :: context ( ) ) ]
132219pub struct Error < T , P : Predicate < T > + ?Sized , C : TypeStr + ?Sized = NoContext > {
133220 /// The value that failed to satisfy the predicate.
134221 pub value : T ,
@@ -141,6 +228,48 @@ pub struct Error<T, P: Predicate<T> + ?Sized, C: TypeStr + ?Sized = NoContext> {
141228 pub context : PhantomData < C > ,
142229}
143230
231+ #[ cfg( feature = "alloc" ) ]
232+ use alloc:: string:: { String , ToString } ;
233+
234+ /// Represents errors that retain their message and invalid value.
235+ #[ cfg( any( feature = "alloc" , feature = "std" ) ) ]
236+ #[ derive( Debug , Error ) ]
237+ #[ error( "{message}" ) ]
238+ pub struct ErasedError < T > {
239+ /// The value that failed to satisfy the predicate.
240+ pub value : T ,
241+ /// The expectation message.
242+ pub message : String ,
243+ }
244+
245+ impl < T > ErasedError < T > {
246+ /// Constructs [`Self`].
247+ pub const fn new ( value : T , message : String ) -> Self {
248+ Self { value, message }
249+ }
250+ }
251+
252+ /// Represents errors that only retain their message.
253+ #[ cfg( any( feature = "alloc" , feature = "std" ) ) ]
254+ #[ derive( Debug , Error ) ]
255+ #[ error( "{string}" ) ]
256+ pub struct MessageError {
257+ /// The expectation message.
258+ pub string : String ,
259+ }
260+
261+ impl MessageError {
262+ /// Constructs [`Self`].
263+ pub const fn new ( string : String ) -> Self {
264+ Self { string }
265+ }
266+
267+ /// Returns the expectation message.
268+ pub fn string ( & self ) -> & str {
269+ self . string . as_str ( )
270+ }
271+ }
272+
144273impl < T , P : Predicate < T > + ?Sized , C : TypeStr + ?Sized > Error < T , P , C > {
145274 /// Constructs [`Self`].
146275 pub const fn new ( value : T , error : P :: Error ) -> Self {
@@ -167,6 +296,34 @@ impl<T, P: Predicate<T> + ?Sized, C: TypeStr + ?Sized> Error<T, P, C> {
167296 }
168297}
169298
299+ impl < T , P : Predicate < T > + ?Sized , C : TypeStr + ?Sized > Error < T , P , C > {
300+ /// Erases the source error, retaining only the value and the expectation message.
301+ pub fn erase ( self ) -> ErasedError < T > {
302+ let string = self . to_string ( ) ;
303+
304+ ErasedError :: new ( self . value , string)
305+ }
306+ }
307+
308+ impl < T , P : Predicate < T > + ?Sized , C : TypeStr + ?Sized > Error < T , P , C > {
309+ /// Erases the source error and discards the value, retaining only the expectation message.
310+ pub fn message ( & self ) -> MessageError {
311+ MessageError :: new ( self . to_string ( ) )
312+ }
313+ }
314+
315+ impl < T , P : Predicate < T > + ?Sized , C : TypeStr + ?Sized > From < Error < T , P , C > > for ErasedError < T > {
316+ fn from ( error : Error < T , P , C > ) -> Self {
317+ error. erase ( )
318+ }
319+ }
320+
321+ impl < T , P : Predicate < T > + ?Sized , C : TypeStr + ?Sized > From < Error < T , P , C > > for MessageError {
322+ fn from ( error : Error < T , P , C > ) -> Self {
323+ error. message ( )
324+ }
325+ }
326+
170327impl < T , P : Predicate < T > + ?Sized , C : TypeStr + ?Sized > Error < T , P , C > {
171328 /// Returns the contained value and the received error.
172329 pub fn into_parts ( self ) -> ( T , P :: Error ) {
@@ -206,7 +363,7 @@ impl<T, P: Predicate<T> + ?Sized, C: TypeStr + ?Sized> Refinement<T, P, C> {
206363 ///
207364 /// Returns [`struct@Error`] if the resulting value does not satisfy the predicate.
208365 pub fn map < F : FnOnce ( T ) -> T > ( self , function : F ) -> Result < Self , Error < T , P , C > > {
209- Self :: refine ( function ( self . value ) )
366+ Self :: refine ( function ( self . take ( ) ) )
210367 }
211368
212369 /// Replaces the value of the refinement.
@@ -218,8 +375,8 @@ impl<T, P: Predicate<T> + ?Sized, C: TypeStr + ?Sized> Refinement<T, P, C> {
218375 Self :: refine ( value)
219376 }
220377
221- /// Extracts the value from the refinement.
222- pub fn extract ( self ) -> T {
378+ /// Takes the value from the refinement.
379+ pub fn take ( self ) -> T {
223380 self . value
224381 }
225382
@@ -228,30 +385,3 @@ impl<T, P: Predicate<T> + ?Sized, C: TypeStr + ?Sized> Refinement<T, P, C> {
228385 & self . value
229386 }
230387}
231-
232- impl < T : Default , P : Predicate < T > + ?Sized , C : TypeStr + ?Sized > Refinement < T , P , C > {
233- /// Refines the default value of type `T`.
234- ///
235- /// # Errors
236- ///
237- /// Returns [`struct@Error`] if the default value does not satisfy the predicate.
238- pub fn try_default ( ) -> Result < Self , Error < T , P , C > > {
239- Self :: refine ( T :: default ( ) )
240- }
241- }
242-
243- impl < T : fmt:: Display , P : Predicate < T > + ?Sized , C : TypeStr + ?Sized > fmt:: Display
244- for Refinement < T , P , C >
245- {
246- fn fmt ( & self , formatter : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
247- self . value . fmt ( formatter)
248- }
249- }
250-
251- impl < T , P : Predicate < T > + ?Sized , C : TypeStr + ?Sized > Deref for Refinement < T , P , C > {
252- type Target = T ;
253-
254- fn deref ( & self ) -> & Self :: Target {
255- self . get ( )
256- }
257- }
0 commit comments