reflect_tools/reflect/wrapper/
optional_cow.rs

1//!
2//! It's often necessary to wrap something inot a local structure and this file contains wrapper of `Option< Cow< 'a, T > >`.
3//!
4
5use core::fmt;
6use std::borrow::Cow;
7use core::ops::{ Deref };
8
9/// Universal wrapper with transparent option of copy on write reference emphasizing a specific aspect of identity of its internal type.
10#[ repr( transparent ) ]
11pub struct OptionalCow< 'a, T, Marker >( pub Option< Cow< 'a, T > >, ::core::marker::PhantomData< fn() -> Marker > )
12where
13  T : std::borrow::ToOwned + ?Sized,
14  Marker : Clone + Copy + 'static,
15;
16
17impl< 'a, T, Marker > OptionalCow< 'a, T, Marker >
18where
19  T : std::borrow::ToOwned + ?Sized,
20  Marker : Clone + Copy + 'static,
21{
22
23  /// Creates owned data from borrowed data, usually by cloning.
24  #[ inline( always ) ]
25  pub fn into_owned( &self ) -> < T as std::borrow::ToOwned >::Owned
26  where
27    < T as std::borrow::ToOwned >::Owned : Default,
28  {
29    match self.0.as_ref()
30    {
31      Some( c ) => c.clone().into_owned(),
32      None => < T as std::borrow::ToOwned >::Owned::default(),
33    }
34  }
35
36  /// Check is it borrowed.
37  #[ inline( always ) ]
38  pub fn is_borrowed( &self ) -> bool
39  {
40    if self.0.is_none()
41    {
42      return false;
43    }
44    match self.0.as_ref().unwrap()
45    {
46      Cow::Borrowed( _ ) => true,
47      Cow::Owned( _ ) => false,
48    }
49  }
50
51  /// Check does it have some value.
52  #[ inline( always ) ]
53  pub fn is_some( &self ) -> bool
54  {
55    return self.0.is_some()
56  }
57
58  /// Constructor returning none.
59  #[ inline( always ) ]
60  pub fn none() -> Self
61  {
62    Self( None, ::core::marker::PhantomData )
63  }
64
65  /// Just a constructor.
66  #[ inline( always ) ]
67  pub fn new( src : < T as std::borrow::ToOwned >::Owned ) -> Self
68  {
69    Self( Some( Cow::Owned( src ) ), ::core::marker::PhantomData )
70  }
71
72  // xxx : review
73  /// Just a constructor.
74  #[ inline( always ) ]
75  pub fn new_with_ref( src : &'a T ) -> Self
76  {
77    Self( Some( Cow::Borrowed( src ) ), ::core::marker::PhantomData )
78  }
79
80  /// Just a constructor.
81  #[ inline( always ) ]
82  pub fn new_with_inner( src : Option< Cow< 'a, T > > ) -> Self
83  {
84    Self( src, ::core::marker::PhantomData )
85  }
86
87  /// Just a constructor.
88  #[ inline( always ) ]
89  pub fn inner( self ) -> Option< Cow< 'a, T > >
90  {
91    self.0
92  }
93
94}
95
96// impl< 'a, T, Marker > std::borrow::ToOwned for OptionalCow< 'a, T, Marker >
97// where
98//   T : std::borrow::ToOwned + ?Sized,
99// {
100//   type Owned = OptionalCow< 'static, T::Owned, Marker >;
101//
102//   fn to_owned( &self ) -> Self::Owned
103//   {
104//     OptionalCow
105//     (
106//       self.0.as_ref().map( | cow | Cow::Owned( cow.to_owned() ) ),
107//       std::marker::PhantomData
108//     )
109//   }
110// }
111
112impl< 'a, T, Marker > Clone for OptionalCow< 'a, T, Marker >
113where
114  T : std::borrow::ToOwned + ?Sized,
115  Marker : Clone + Copy + 'static,
116{
117  fn clone( &self ) -> Self
118  {
119    Self( self.0.clone(), ::core::marker::PhantomData )
120  }
121}
122
123impl< 'a, T, Marker > AsRef< Option< Cow< 'a, T > > > for OptionalCow< 'a, T, Marker >
124where
125  T : std::borrow::ToOwned + ?Sized,
126  Marker : Clone + Copy + 'static,
127{
128  fn as_ref( &self ) -> &Option< Cow< 'a, T > >
129  {
130    &self.0
131  }
132}
133
134impl< 'a, T, Marker > Deref for OptionalCow< 'a, T, Marker >
135where
136  T : std::borrow::ToOwned + ?Sized,
137  Marker : Clone + Copy + 'static,
138{
139  type Target = Option< Cow< 'a, T > >;
140  fn deref( &self ) -> &Option< Cow< 'a, T > >
141  {
142    self.as_ref()
143  }
144}
145
146impl< 'a, T, Marker > From< Cow< 'a, T > >
147for OptionalCow< 'a, T, Marker >
148where
149  T : std::borrow::ToOwned + ?Sized,
150  Marker : Clone + Copy + 'static,
151{
152  fn from( src : Cow< 'a, T > ) -> Self
153  {
154    OptionalCow::new_with_inner( Some( src ) )
155  }
156}
157
158impl< 'a, T, Marker > From< Option< Cow< 'a, T > > >
159for OptionalCow< 'a, T, Marker >
160where
161  T : std::borrow::ToOwned + ?Sized,
162  Marker : Clone + Copy + 'static,
163{
164  fn from( src : Option< Cow< 'a, T > > ) -> Self
165  {
166    OptionalCow::new_with_inner( src )
167  }
168}
169
170impl< 'a, T, Marker > From< &'a T >
171for OptionalCow< 'a, T, Marker >
172where
173  T : std::borrow::ToOwned + ?Sized,
174  Marker : Clone + Copy + 'static,
175{
176  fn from( src : &'a T ) -> Self
177  {
178    OptionalCow::new_with_ref( src )
179  }
180}
181
182impl< 'a, T, Marker > Default for OptionalCow< 'a, T, Marker >
183where
184  T : std::borrow::ToOwned + ?Sized,
185  < T as std::borrow::ToOwned >::Owned : Default,
186  Marker : Clone + Copy + 'static,
187{
188  fn default() -> Self
189  {
190    OptionalCow::new( < T as std::borrow::ToOwned >::Owned::default() )
191  }
192}
193
194impl< 'a, T, Marker > fmt::Debug for OptionalCow< 'a, T, Marker >
195where
196  T : std::borrow::ToOwned + ?Sized,
197  < T as std::borrow::ToOwned >::Owned : fmt::Debug,
198  Marker : Clone + Copy + 'static,
199  T : fmt::Debug,
200{
201  fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> fmt::Result
202  {
203    f.debug_struct( "OptionalCow" )
204    .field( "0", &self.0 )
205    .finish()
206  }
207}
208
209impl< 'a, T, Marker > PartialEq for OptionalCow< 'a, T, Marker >
210where
211  T : std::borrow::ToOwned + ?Sized,
212  Marker : Clone + Copy + 'static,
213  T : PartialEq,
214{
215  fn eq( &self, other : &Self ) -> bool
216  {
217    self.as_ref() == other.as_ref()
218  }
219}
220
221impl< 'a, T, Marker > Eq for OptionalCow< 'a, T, Marker >
222where
223  T : std::borrow::ToOwned + ?Sized,
224  Marker : Clone + Copy + 'static,
225  T : Eq,
226{
227}
228
229impl< 'a, T, Marker > From< OptionalCow< 'a, T, Marker > > for Option< Cow< 'a, T > >
230where
231  T : std::borrow::ToOwned + ?Sized,
232  Marker : Clone + Copy + 'static,
233{
234  #[ inline( always ) ]
235  fn from( src : OptionalCow< 'a, T, Marker > ) -> Self
236  {
237    src.0
238  }
239}