|
1 | 1 | use std::{borrow::Cow, fmt, hash::Hash, slice, vec}; |
2 | 2 |
|
3 | 3 | use arcstr::ArcStr; |
| 4 | +use compact_str::CompactString; |
4 | 5 |
|
5 | 6 | use indexmap::IndexMap; |
6 | 7 |
|
@@ -249,10 +250,7 @@ impl<S> InputValue<S> { |
249 | 250 | } |
250 | 251 |
|
251 | 252 | /// Construct a scalar value |
252 | | - pub fn scalar<T>(v: T) -> Self |
253 | | - where |
254 | | - S: From<T>, |
255 | | - { |
| 253 | + pub fn scalar<T: Into<S>>(v: T) -> Self { |
256 | 254 | Self::Scalar(v.into()) |
257 | 255 | } |
258 | 256 |
|
@@ -509,51 +507,117 @@ impl<S: ScalarValue> fmt::Display for InputValue<S> { |
509 | 507 | } |
510 | 508 | } |
511 | 509 |
|
512 | | -impl<S, T> From<Option<T>> for InputValue<S> |
| 510 | +/// Conversion into an [`InputValue`]. |
| 511 | +/// |
| 512 | +/// This trait exists to work around [orphan rules] and allow to specify custom efficient |
| 513 | +/// conversions whenever some custom [`ScalarValue`] is involved |
| 514 | +/// (`impl IntoInputValue<CustomScalarValue> for ForeignType` would work, while |
| 515 | +/// `impl From<ForeignType> for InputValue<CustomScalarValue>` wound not). |
| 516 | +/// |
| 517 | +/// This trait is used inside [`graphql_input_value!`] macro expansion and implementing it allows to |
| 518 | +/// put values of the implementor type there. |
| 519 | +/// |
| 520 | +/// [`graphql_input_value!`]: crate::graphql_input_value |
| 521 | +/// [orphan rules]: https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules |
| 522 | +pub trait IntoInputValue<S> { |
| 523 | + /// Converts this value into an [`InputValue`]. |
| 524 | + #[must_use] |
| 525 | + fn into_input_value(self) -> InputValue<S>; |
| 526 | +} |
| 527 | + |
| 528 | +impl<S> IntoInputValue<S> for InputValue<S> { |
| 529 | + fn into_input_value(self) -> Self { |
| 530 | + self |
| 531 | + } |
| 532 | +} |
| 533 | + |
| 534 | +impl<T, S> IntoInputValue<S> for Option<T> |
513 | 535 | where |
514 | | - Self: From<T>, |
| 536 | + T: IntoInputValue<S>, |
515 | 537 | { |
516 | | - fn from(v: Option<T>) -> Self { |
517 | | - match v { |
518 | | - Some(v) => v.into(), |
519 | | - None => Self::Null, |
| 538 | + fn into_input_value(self) -> InputValue<S> { |
| 539 | + match self { |
| 540 | + Some(v) => v.into_input_value(), |
| 541 | + None => InputValue::Null, |
520 | 542 | } |
521 | 543 | } |
522 | 544 | } |
523 | 545 |
|
524 | | -impl<'a, S: From<String>> From<&'a str> for InputValue<S> { |
525 | | - fn from(s: &'a str) -> Self { |
526 | | - Self::scalar(s.to_owned()) |
| 546 | +impl<S> IntoInputValue<S> for &str |
| 547 | +where |
| 548 | + String: Into<S>, |
| 549 | +{ |
| 550 | + fn into_input_value(self) -> InputValue<S> { |
| 551 | + InputValue::scalar(self.to_owned()) |
| 552 | + } |
| 553 | +} |
| 554 | + |
| 555 | +impl<S> IntoInputValue<S> for Cow<'_, str> |
| 556 | +where |
| 557 | + String: Into<S>, |
| 558 | +{ |
| 559 | + fn into_input_value(self) -> InputValue<S> { |
| 560 | + InputValue::scalar(self.into_owned()) |
| 561 | + } |
| 562 | +} |
| 563 | + |
| 564 | +impl<S> IntoInputValue<S> for String |
| 565 | +where |
| 566 | + String: Into<S>, |
| 567 | +{ |
| 568 | + fn into_input_value(self) -> InputValue<S> { |
| 569 | + InputValue::scalar(self) |
| 570 | + } |
| 571 | +} |
| 572 | + |
| 573 | +impl<S: ScalarValue> IntoInputValue<S> for &ArcStr { |
| 574 | + fn into_input_value(self) -> InputValue<S> { |
| 575 | + InputValue::scalar(S::from_displayable(self)) |
527 | 576 | } |
528 | 577 | } |
529 | 578 |
|
530 | | -impl<'a, S: From<String>> From<Cow<'a, str>> for InputValue<S> { |
531 | | - fn from(s: Cow<'a, str>) -> Self { |
532 | | - Self::scalar(s.into_owned()) |
| 579 | +impl<S: ScalarValue> IntoInputValue<S> for ArcStr { |
| 580 | + fn into_input_value(self) -> InputValue<S> { |
| 581 | + (&self).into_input_value() |
533 | 582 | } |
534 | 583 | } |
535 | 584 |
|
536 | | -impl<S: From<String>> From<String> for InputValue<S> { |
537 | | - fn from(s: String) -> Self { |
538 | | - Self::scalar(s) |
| 585 | +impl<S: ScalarValue> IntoInputValue<S> for &CompactString { |
| 586 | + fn into_input_value(self) -> InputValue<S> { |
| 587 | + InputValue::scalar(S::from_displayable(self)) |
539 | 588 | } |
540 | 589 | } |
541 | 590 |
|
542 | | -impl<S: From<i32>> From<i32> for InputValue<S> { |
543 | | - fn from(i: i32) -> Self { |
544 | | - Self::scalar(i) |
| 591 | +impl<S: ScalarValue> IntoInputValue<S> for CompactString { |
| 592 | + fn into_input_value(self) -> InputValue<S> { |
| 593 | + (&self).into_input_value() |
545 | 594 | } |
546 | 595 | } |
547 | 596 |
|
548 | | -impl<S: From<f64>> From<f64> for InputValue<S> { |
549 | | - fn from(f: f64) -> Self { |
550 | | - Self::scalar(f) |
| 597 | +impl<S> IntoInputValue<S> for i32 |
| 598 | +where |
| 599 | + i32: Into<S>, |
| 600 | +{ |
| 601 | + fn into_input_value(self) -> InputValue<S> { |
| 602 | + InputValue::scalar(self) |
551 | 603 | } |
552 | 604 | } |
553 | 605 |
|
554 | | -impl<S: From<bool>> From<bool> for InputValue<S> { |
555 | | - fn from(b: bool) -> Self { |
556 | | - Self::scalar(b) |
| 606 | +impl<S> IntoInputValue<S> for f64 |
| 607 | +where |
| 608 | + f64: Into<S>, |
| 609 | +{ |
| 610 | + fn into_input_value(self) -> InputValue<S> { |
| 611 | + InputValue::scalar(self) |
| 612 | + } |
| 613 | +} |
| 614 | + |
| 615 | +impl<S> IntoInputValue<S> for bool |
| 616 | +where |
| 617 | + bool: Into<S>, |
| 618 | +{ |
| 619 | + fn into_input_value(self) -> InputValue<S> { |
| 620 | + InputValue::scalar(self) |
557 | 621 | } |
558 | 622 | } |
559 | 623 |
|
|
0 commit comments