@@ -428,8 +428,10 @@ impl WrongType {
428
428
///
429
429
/// # Arrays
430
430
///
431
- /// `FromSql` is implemented for `Vec<T>` where `T` implements `FromSql`, and
432
- /// corresponds to one-dimensional Postgres arrays.
431
+ /// `FromSql` is implemented for `Vec<T>` and `[T; N]` where `T` implements
432
+ /// `FromSql`, and corresponds to one-dimensional Postgres arrays. **Note:**
433
+ /// the impl for arrays only exist when the Cargo feature `array-impls` is
434
+ /// enabled.
433
435
pub trait FromSql < ' a > : Sized {
434
436
/// Creates a new value of this type from a buffer of data of the specified
435
437
/// Postgres `Type` in its binary format.
@@ -513,6 +515,47 @@ impl<'a, T: FromSql<'a>> FromSql<'a> for Vec<T> {
513
515
}
514
516
}
515
517
518
+ #[ cfg( feature = "array-impls" ) ]
519
+ impl < ' a , T : FromSql < ' a > , const N : usize > FromSql < ' a > for [ T ; N ] {
520
+ fn from_sql ( ty : & Type , raw : & ' a [ u8 ] ) -> Result < Self , Box < dyn Error + Sync + Send > > {
521
+ let member_type = match * ty. kind ( ) {
522
+ Kind :: Array ( ref member) => member,
523
+ _ => panic ! ( "expected array type" ) ,
524
+ } ;
525
+
526
+ let array = types:: array_from_sql ( raw) ?;
527
+ if array. dimensions ( ) . count ( ) ? > 1 {
528
+ return Err ( "array contains too many dimensions" . into ( ) ) ;
529
+ }
530
+
531
+ let mut values = array. values ( ) ;
532
+ let out = array_init:: try_array_init ( |i| {
533
+ let v = values
534
+ . next ( ) ?
535
+ . ok_or_else ( || -> Box < dyn Error + Sync + Send > {
536
+ format ! ( "too few elements in array (expected {}, got {})" , N , i) . into ( )
537
+ } ) ?;
538
+ T :: from_sql_nullable ( member_type, v)
539
+ } ) ?;
540
+ if values. next ( ) ?. is_some ( ) {
541
+ return Err ( format ! (
542
+ "excess elements in array (expected {}, got more than that)" ,
543
+ N ,
544
+ )
545
+ . into ( ) ) ;
546
+ }
547
+
548
+ Ok ( out)
549
+ }
550
+
551
+ fn accepts ( ty : & Type ) -> bool {
552
+ match * ty. kind ( ) {
553
+ Kind :: Array ( ref inner) => T :: accepts ( inner) ,
554
+ _ => false ,
555
+ }
556
+ }
557
+ }
558
+
516
559
impl < ' a > FromSql < ' a > for Vec < u8 > {
517
560
fn from_sql ( _: & Type , raw : & ' a [ u8 ] ) -> Result < Vec < u8 > , Box < dyn Error + Sync + Send > > {
518
561
Ok ( types:: bytea_from_sql ( raw) . to_owned ( ) )
@@ -691,8 +734,10 @@ pub enum IsNull {
691
734
///
692
735
/// # Arrays
693
736
///
694
- /// `ToSql` is implemented for `Vec<T>` and `&[T]` where `T` implements `ToSql`,
695
- /// and corresponds to one-dimensional Postgres arrays with an index offset of 1.
737
+ /// `ToSql` is implemented for `Vec<T>`, `&[T]` and `[T; N]` where `T`
738
+ /// implements `ToSql`, and corresponds to one-dimensional Postgres arrays with
739
+ /// an index offset of 1. **Note:** the impl for arrays only exist when the
740
+ /// Cargo feature `array-impls` is enabled.
696
741
pub trait ToSql : fmt:: Debug {
697
742
/// Converts the value of `self` into the binary format of the specified
698
743
/// Postgres `Type`, appending it to `out`.
@@ -808,6 +853,19 @@ impl<'a> ToSql for &'a [u8] {
808
853
to_sql_checked ! ( ) ;
809
854
}
810
855
856
+ #[ cfg( feature = "array-impls" ) ]
857
+ impl < T : ToSql , const N : usize > ToSql for [ T ; N ] {
858
+ fn to_sql ( & self , ty : & Type , w : & mut BytesMut ) -> Result < IsNull , Box < dyn Error + Sync + Send > > {
859
+ <& [ T ] as ToSql >:: to_sql ( & & self [ ..] , ty, w)
860
+ }
861
+
862
+ fn accepts ( ty : & Type ) -> bool {
863
+ <& [ T ] as ToSql >:: accepts ( ty)
864
+ }
865
+
866
+ to_sql_checked ! ( ) ;
867
+ }
868
+
811
869
impl < T : ToSql > ToSql for Vec < T > {
812
870
fn to_sql ( & self , ty : & Type , w : & mut BytesMut ) -> Result < IsNull , Box < dyn Error + Sync + Send > > {
813
871
<& [ T ] as ToSql >:: to_sql ( & & * * self , ty, w)
0 commit comments