@@ -175,8 +175,8 @@ pub enum Value {
175
175
Boolean ( bool ) ,
176
176
/// `NULL` value
177
177
Null ,
178
- /// `?` or `$` Prepared statement arg placeholder
179
- Placeholder ( String ) ,
178
+ /// `?`, `$`, or ':' prepared statement arg placeholder
179
+ Placeholder ( Placeholder ) ,
180
180
}
181
181
182
182
impl ValueWithSpan {
@@ -591,3 +591,129 @@ impl fmt::Display for TrimWhereField {
591
591
} )
592
592
}
593
593
}
594
+
595
+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
596
+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
597
+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
598
+ pub enum PlaceholderKind {
599
+ /// A placeholder derived by the parser, not explicitly demarcated
600
+ /// in the parsed input.
601
+ Derived ,
602
+
603
+ /// Example:
604
+ /// ```sql
605
+ /// SELECT ?, ?1, ?2
606
+ /// ```
607
+ /// Supports only [PlaceholderValue::None] and [PlaceholderValue::Number] values
608
+ QuestionMark ,
609
+
610
+ /// Example:
611
+ /// ```sql
612
+ /// SELECT @foo, @1, @2
613
+ /// ```
614
+ /// Supports only [PlaceholderValue::Label] and [PlaceholderValue::Number] values
615
+ AtSign ,
616
+
617
+ /// Example:
618
+ /// ```sql
619
+ /// SELECT $, $1, $2, $foo
620
+ /// ```
621
+ /// Supports all [PlaceholderValue::None], [PlaceholderValue::Label],
622
+ /// and [PlaceholderValue::Number] variants
623
+ Dollar ,
624
+
625
+ /// Example:
626
+ /// ```sql
627
+ /// SELECT :1, :foo
628
+ /// ```
629
+ /// Supports only [PlaceholderValue::Label] and [PlaceholderValue::Number] values
630
+ Colon ,
631
+ }
632
+
633
+ impl fmt:: Display for PlaceholderKind {
634
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
635
+ write ! (
636
+ f,
637
+ "{}" ,
638
+ match self {
639
+ PlaceholderKind :: Derived => "" ,
640
+ PlaceholderKind :: QuestionMark => "?" ,
641
+ PlaceholderKind :: AtSign => "@" ,
642
+ PlaceholderKind :: Dollar => "$" ,
643
+ PlaceholderKind :: Colon => ":" ,
644
+ }
645
+ )
646
+ }
647
+ }
648
+
649
+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
650
+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
651
+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
652
+ pub enum PlaceholderValue {
653
+ /// An innominate (ie. unnamed and non-numbered) placeholder,
654
+ /// e.g. `SELECT ?` or `SELECT $`
655
+ None ,
656
+ /// A label / name of a named placeholder,
657
+ /// e.g. `"foo"` in `SELECT :foo`
658
+ Name ( String ) ,
659
+ /// The number value of a numbered placeholder,
660
+ /// e.g. `42` in `SELECT ?42` or `SELECT $42`
661
+ Number ( u32 ) ,
662
+ }
663
+
664
+ impl fmt:: Display for PlaceholderValue {
665
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
666
+ match self {
667
+ PlaceholderValue :: None => Ok ( ( ) ) ,
668
+ PlaceholderValue :: Name ( ref s) => f. write_str ( s) ,
669
+ PlaceholderValue :: Number ( n) => write ! ( f, "{n}" ) ,
670
+ }
671
+ }
672
+ }
673
+
674
+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
675
+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
676
+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
677
+ pub struct Placeholder {
678
+ pub kind : PlaceholderKind ,
679
+ pub value : PlaceholderValue ,
680
+ }
681
+
682
+ impl From < Placeholder > for Value {
683
+ fn from ( value : Placeholder ) -> Self {
684
+ Value :: Placeholder ( value)
685
+ }
686
+ }
687
+
688
+ impl Placeholder {
689
+ pub fn innominate ( kind : PlaceholderKind ) -> Self {
690
+ Self {
691
+ kind,
692
+ value : PlaceholderValue :: None ,
693
+ }
694
+ }
695
+
696
+ pub fn named < S : Into < String > > ( kind : PlaceholderKind , label : S ) -> Self {
697
+ Self {
698
+ kind,
699
+ value : PlaceholderValue :: Name ( label. into ( ) ) ,
700
+ }
701
+ }
702
+
703
+ pub fn numbered ( kind : PlaceholderKind , number : u32 ) -> Self {
704
+ Self {
705
+ kind,
706
+ value : PlaceholderValue :: Number ( number) ,
707
+ }
708
+ }
709
+
710
+ pub fn into_value ( self ) -> Value {
711
+ self . into ( )
712
+ }
713
+ }
714
+
715
+ impl fmt:: Display for Placeholder {
716
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
717
+ write ! ( f, "{}{}" , self . kind, self . value)
718
+ }
719
+ }
0 commit comments