1use rusqlite::{Result, Row};
2
3pub trait Decode: Sized {
4 const N_COLS: usize;
5 fn decode_at(row: &Row<'_>, col_offset: usize) -> Result<Self>;
6 fn decode(row: &Row<'_>) -> Result<Self> {
7 Self::decode_at(row, 0)
8 }
9}
10
11impl Decode for i8 {
12 const N_COLS: usize = 1;
13 fn decode_at(row: &Row<'_>, off: usize) -> Result<Self> {
14 row.get(off)
15 }
16}
17impl Decode for i16 {
18 const N_COLS: usize = 1;
19 fn decode_at(row: &Row<'_>, off: usize) -> Result<Self> {
20 row.get(off)
21 }
22}
23impl Decode for i32 {
24 const N_COLS: usize = 1;
25 fn decode_at(row: &Row<'_>, off: usize) -> Result<Self> {
26 row.get(off)
27 }
28}
29impl Decode for i64 {
30 const N_COLS: usize = 1;
31 fn decode_at(row: &Row<'_>, off: usize) -> Result<Self> {
32 row.get(off)
33 }
34}
35impl Decode for isize {
36 const N_COLS: usize = 1;
37 fn decode_at(row: &Row<'_>, off: usize) -> Result<Self> {
38 row.get(off)
39 }
40}
41impl Decode for u8 {
42 const N_COLS: usize = 1;
43 fn decode_at(row: &Row<'_>, off: usize) -> Result<Self> {
44 row.get(off)
45 }
46}
47impl Decode for u16 {
48 const N_COLS: usize = 1;
49 fn decode_at(row: &Row<'_>, off: usize) -> Result<Self> {
50 row.get(off)
51 }
52}
53impl Decode for u32 {
54 const N_COLS: usize = 1;
55 fn decode_at(row: &Row<'_>, off: usize) -> Result<Self> {
56 row.get(off)
57 }
58}
59impl Decode for u64 {
60 const N_COLS: usize = 1;
61 fn decode_at(row: &Row<'_>, off: usize) -> Result<Self> {
62 row.get(off)
63 }
64}
65impl Decode for f32 {
66 const N_COLS: usize = 1;
67 fn decode_at(row: &Row<'_>, off: usize) -> Result<Self> {
68 row.get(off)
69 }
70}
71impl Decode for f64 {
72 const N_COLS: usize = 1;
73 fn decode_at(row: &Row<'_>, off: usize) -> Result<Self> {
74 row.get(off)
75 }
76}
77impl Decode for bool {
78 const N_COLS: usize = 1;
79 fn decode_at(row: &Row<'_>, off: usize) -> Result<Self> {
80 row.get(off)
81 }
82}
83impl Decode for String {
84 const N_COLS: usize = 1;
85 fn decode_at(row: &Row<'_>, off: usize) -> Result<Self> {
86 row.get(off)
87 }
88}
89impl Decode for Vec<u8> {
90 const N_COLS: usize = 1;
91 fn decode_at(row: &Row<'_>, off: usize) -> Result<Self> {
92 row.get(off)
93 }
94}
95
96impl<T: rusqlite::types::FromSql> Decode for Option<T> {
97 const N_COLS: usize = 1;
98 fn decode_at(row: &Row<'_>, off: usize) -> Result<Self> {
99 row.get(off)
100 }
101}
102
103impl<A: Decode, B: Decode> Decode for (A, B) {
104 const N_COLS: usize = A::N_COLS + B::N_COLS;
105 fn decode_at(row: &Row<'_>, off: usize) -> Result<Self> {
106 let a = A::decode_at(row, off)?;
107 let b = B::decode_at(row, off + A::N_COLS)?;
108 Ok((a, b))
109 }
110}
111impl<A: Decode, B: Decode, C: Decode> Decode for (A, B, C) {
112 const N_COLS: usize = A::N_COLS + B::N_COLS + C::N_COLS;
113 fn decode_at(row: &Row<'_>, off: usize) -> Result<Self> {
114 let a = A::decode_at(row, off)?;
115 let b = B::decode_at(row, off + A::N_COLS)?;
116 let c = C::decode_at(row, off + A::N_COLS + B::N_COLS)?;
117 Ok((a, b, c))
118 }
119}
120impl<A: Decode, B: Decode, C: Decode, D: Decode> Decode for (A, B, C, D) {
121 const N_COLS: usize = A::N_COLS + B::N_COLS + C::N_COLS + D::N_COLS;
122 fn decode_at(row: &Row<'_>, off: usize) -> Result<Self> {
123 let a = A::decode_at(row, off)?;
124 let b = B::decode_at(row, off + A::N_COLS)?;
125 let c = C::decode_at(row, off + A::N_COLS + B::N_COLS)?;
126 let d = D::decode_at(row, off + A::N_COLS + B::N_COLS + C::N_COLS)?;
127 Ok((a, b, c, d))
128 }
129}