@@ -4,6 +4,7 @@ mod scalar;
44use std:: { any:: TypeId , borrow:: Cow , fmt, mem} ;
55
66use arcstr:: ArcStr ;
7+ use compact_str:: CompactString ;
78use derive_more:: with_trait:: From ;
89
910use crate :: {
@@ -13,7 +14,7 @@ use crate::{
1314
1415pub use self :: {
1516 object:: Object ,
16- scalar:: { DefaultScalarValue , ParseScalarResult , ParseScalarValue , ScalarValue , AnyExt } ,
17+ scalar:: { AnyExt , DefaultScalarValue , ParseScalarResult , ParseScalarValue , ScalarValue } ,
1718} ;
1819
1920/// Serializable value returned from query and field execution.
@@ -54,10 +55,7 @@ impl<S> Value<S> {
5455 }
5556
5657 /// Construct a scalar value
57- pub fn scalar < T > ( s : T ) -> Self
58- where
59- S : From < T > ,
60- {
58+ pub fn scalar < T : Into < S > > ( s : T ) -> Self {
6159 Self :: Scalar ( s. into ( ) )
6260 }
6361
@@ -234,73 +232,117 @@ impl<S: ScalarValue> fmt::Display for Value<S> {
234232 }
235233}
236234
237- impl < S , T > From < Option < T > > for Value < S >
235+ /// Conversion into a [`Value`].
236+ ///
237+ /// This trait exists to work around [orphan rules] and allow to specify custom efficient
238+ /// conversions whenever some custom [`ScalarValue`] is involved
239+ /// (`impl IntoValue<CustomScalarValue> for ForeignType` would work, while
240+ /// `impl From<ForeignType> for Value<CustomScalarValue>` wound not).
241+ ///
242+ /// This trait is used inside [`graphql_value!`] macro expansion and implementing it allows to
243+ /// put values of the implementor type there.
244+ ///
245+ /// [`graphql_value!`]: crate::graphql_value
246+ /// [orphan rules]: https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules
247+ pub trait IntoValue < S > {
248+ /// Converts this value into a [`Value`].
249+ #[ must_use]
250+ fn into_value ( self ) -> Value < S > ;
251+ }
252+
253+ impl < S > IntoValue < S > for Value < S > {
254+ fn into_value ( self ) -> Self {
255+ self
256+ }
257+ }
258+
259+ impl < T , S > IntoValue < S > for Option < T >
238260where
239- Self : From < T > ,
261+ T : IntoValue < S > ,
240262{
241- fn from ( v : Option < T > ) -> Self {
242- match v {
243- Some ( v) => v. into ( ) ,
244- None => Self :: Null ,
263+ fn into_value ( self ) -> Value < S > {
264+ match self {
265+ Some ( v) => v. into_value ( ) ,
266+ None => Value :: Null ,
245267 }
246268 }
247269}
248270
249- impl < ' a , S : From < String > > From < & ' a str > for Value < S > {
250- fn from ( s : & ' a str ) -> Self {
251- Self :: scalar ( s. to_owned ( ) )
271+ impl < S > IntoValue < S > for & str
272+ where
273+ String : Into < S > ,
274+ {
275+ fn into_value ( self ) -> Value < S > {
276+ Value :: scalar ( self . to_owned ( ) )
252277 }
253278}
254279
255- impl < S : ScalarValue > From < & ArcStr > for Value < S > {
256- fn from ( value : & ArcStr ) -> Self {
257- Self :: scalar ( S :: from_custom_string ( value) )
280+ impl < S > IntoValue < S > for Cow < ' _ , str >
281+ where
282+ String : Into < S > ,
283+ {
284+ fn into_value ( self ) -> Value < S > {
285+ Value :: scalar ( self . into_owned ( ) )
258286 }
259287}
260288
261- impl < ' a , S : From < String > > From < Cow < ' a , str > > for Value < S > {
262- fn from ( s : Cow < ' a , str > ) -> Self {
263- Self :: scalar ( s. into_owned ( ) )
289+ impl < S > IntoValue < S > for String
290+ where
291+ String : Into < S > ,
292+ {
293+ fn into_value ( self ) -> Value < S > {
294+ Value :: scalar ( self )
264295 }
265296}
266297
267- impl < S : From < String > > From < String > for Value < S > {
268- fn from ( s : String ) -> Self {
269- Self :: scalar ( s )
298+ impl < S : ScalarValue > IntoValue < S > for & ArcStr {
299+ fn into_value ( self ) -> Value < S > {
300+ Value :: scalar ( S :: from_custom_string ( self ) )
270301 }
271302}
272303
273- impl < S : From < i32 > > From < i32 > for Value < S > {
274- fn from ( i : i32 ) -> Self {
275- Self :: scalar ( i )
304+ impl < S : ScalarValue > IntoValue < S > for ArcStr {
305+ fn into_value ( self ) -> Value < S > {
306+ ( & self ) . into_value ( )
276307 }
277308}
278309
279- impl < S : From < f64 > > From < f64 > for Value < S > {
280- fn from ( f : f64 ) -> Self {
281- Self :: scalar ( f )
310+ impl < S : ScalarValue > IntoValue < S > for & CompactString {
311+ fn into_value ( self ) -> Value < S > {
312+ Value :: scalar ( S :: from_custom_string ( self ) )
282313 }
283314}
284315
285- impl < S : From < bool > > From < bool > for Value < S > {
286- fn from ( b : bool ) -> Self {
287- Self :: scalar ( b )
316+ impl < S : ScalarValue > IntoValue < S > for CompactString {
317+ fn into_value ( self ) -> Value < S > {
318+ ( & self ) . into_value ( )
288319 }
289320}
290321
291- pub trait IntoValue < S > {
292- fn into_value ( self ) -> Value < S > ;
322+ impl < S > IntoValue < S > for i32
323+ where
324+ i32 : Into < S > ,
325+ {
326+ fn into_value ( self ) -> Value < S > {
327+ Value :: scalar ( self )
328+ }
293329}
294330
295- impl < T : Into < Value < S > > , S > IntoValue < S > for T {
331+ impl < S > IntoValue < S > for f64
332+ where
333+ f64 : Into < S > ,
334+ {
296335 fn into_value ( self ) -> Value < S > {
297- self . into ( )
336+ Value :: scalar ( self )
298337 }
299338}
300339
301- impl IntoValue < DefaultScalarValue > for compact_str:: CompactString {
302- fn into_value ( self ) -> Value {
303- todo ! ( )
340+ impl < S > IntoValue < S > for bool
341+ where
342+ bool : Into < S > ,
343+ {
344+ fn into_value ( self ) -> Value < S > {
345+ Value :: scalar ( self )
304346 }
305347}
306348
0 commit comments