@@ -8,32 +8,32 @@ use thiserror::Error;
8
8
9
9
use super :: escape;
10
10
11
- // === SqlSerializerError ===
11
+ // === SerializerError ===
12
12
13
13
#[ derive( Debug , Error ) ]
14
- enum SqlSerializerError {
14
+ enum SerializerError {
15
15
#[ error( "{0} is unsupported" ) ]
16
16
Unsupported ( & ' static str ) ,
17
17
#[ error( "{0}" ) ]
18
18
Custom ( String ) ,
19
19
}
20
20
21
- impl ser:: Error for SqlSerializerError {
21
+ impl ser:: Error for SerializerError {
22
22
fn custom < T : fmt:: Display > ( msg : T ) -> Self {
23
23
Self :: Custom ( msg. to_string ( ) )
24
24
}
25
25
}
26
26
27
- impl From < fmt:: Error > for SqlSerializerError {
27
+ impl From < fmt:: Error > for SerializerError {
28
28
fn from ( err : fmt:: Error ) -> Self {
29
29
Self :: Custom ( err. to_string ( ) )
30
30
}
31
31
}
32
32
33
33
// === SqlSerializer ===
34
34
35
- type Result < T = ( ) , E = SqlSerializerError > = std:: result:: Result < T , E > ;
36
- type Impossible = ser:: Impossible < ( ) , SqlSerializerError > ;
35
+ type Result < T = ( ) , E = SerializerError > = std:: result:: Result < T , E > ;
36
+ type Impossible = ser:: Impossible < ( ) , SerializerError > ;
37
37
38
38
struct SqlSerializer < ' a , W > {
39
39
writer : & ' a mut W ,
@@ -43,7 +43,7 @@ macro_rules! unsupported {
43
43
( $ser_method: ident( $ty: ty) -> $ret: ty, $( $other: tt) * ) => {
44
44
#[ inline]
45
45
fn $ser_method( self , _v: $ty) -> $ret {
46
- Err ( SqlSerializerError :: Unsupported ( stringify!( $ser_method) ) )
46
+ Err ( SerializerError :: Unsupported ( stringify!( $ser_method) ) )
47
47
}
48
48
unsupported!( $( $other) * ) ;
49
49
} ;
@@ -53,7 +53,7 @@ macro_rules! unsupported {
53
53
( $ser_method: ident, $( $other: tt) * ) => {
54
54
#[ inline]
55
55
fn $ser_method( self ) -> Result {
56
- Err ( SqlSerializerError :: Unsupported ( stringify!( $ser_method) ) )
56
+ Err ( SerializerError :: Unsupported ( stringify!( $ser_method) ) )
57
57
}
58
58
unsupported!( $( $other) * ) ;
59
59
} ;
@@ -73,7 +73,7 @@ macro_rules! forward_to_display {
73
73
}
74
74
75
75
impl < ' a , W : Write > Serializer for SqlSerializer < ' a , W > {
76
- type Error = SqlSerializerError ;
76
+ type Error = SerializerError ;
77
77
type Ok = ( ) ;
78
78
type SerializeMap = Impossible ;
79
79
type SerializeSeq = SqlListSerializer < ' a , W > ;
@@ -177,12 +177,12 @@ impl<'a, W: Write> Serializer for SqlSerializer<'a, W> {
177
177
_variant : & ' static str ,
178
178
_value : & T ,
179
179
) -> Result {
180
- Err ( SqlSerializerError :: Unsupported ( "serialize_newtype_variant" ) )
180
+ Err ( SerializerError :: Unsupported ( "serialize_newtype_variant" ) )
181
181
}
182
182
183
183
#[ inline]
184
184
fn serialize_tuple_struct ( self , _name : & ' static str , _len : usize ) -> Result < Impossible > {
185
- Err ( SqlSerializerError :: Unsupported ( "serialize_tuple_struct" ) )
185
+ Err ( SerializerError :: Unsupported ( "serialize_tuple_struct" ) )
186
186
}
187
187
188
188
#[ inline]
@@ -193,12 +193,12 @@ impl<'a, W: Write> Serializer for SqlSerializer<'a, W> {
193
193
_variant : & ' static str ,
194
194
_len : usize ,
195
195
) -> Result < Impossible > {
196
- Err ( SqlSerializerError :: Unsupported ( "serialize_tuple_variant" ) )
196
+ Err ( SerializerError :: Unsupported ( "serialize_tuple_variant" ) )
197
197
}
198
198
199
199
#[ inline]
200
200
fn serialize_struct ( self , _name : & ' static str , _len : usize ) -> Result < Self :: SerializeStruct > {
201
- Err ( SqlSerializerError :: Unsupported ( "serialize_struct" ) )
201
+ Err ( SerializerError :: Unsupported ( "serialize_struct" ) )
202
202
}
203
203
204
204
#[ inline]
@@ -209,7 +209,7 @@ impl<'a, W: Write> Serializer for SqlSerializer<'a, W> {
209
209
_variant : & ' static str ,
210
210
_len : usize ,
211
211
) -> Result < Self :: SerializeStructVariant > {
212
- Err ( SqlSerializerError :: Unsupported ( "serialize_struct_variant" ) )
212
+ Err ( SerializerError :: Unsupported ( "serialize_struct_variant" ) )
213
213
}
214
214
215
215
#[ inline]
@@ -227,7 +227,7 @@ struct SqlListSerializer<'a, W> {
227
227
}
228
228
229
229
impl < ' a , W : Write > SerializeSeq for SqlListSerializer < ' a , W > {
230
- type Error = SqlSerializerError ;
230
+ type Error = SerializerError ;
231
231
type Ok = ( ) ;
232
232
233
233
#[ inline]
@@ -254,7 +254,7 @@ impl<'a, W: Write> SerializeSeq for SqlListSerializer<'a, W> {
254
254
}
255
255
256
256
impl < ' a , W : Write > SerializeTuple for SqlListSerializer < ' a , W > {
257
- type Error = SqlSerializerError ;
257
+ type Error = SerializerError ;
258
258
type Ok = ( ) ;
259
259
260
260
#[ inline]
@@ -271,6 +271,167 @@ impl<'a, W: Write> SerializeTuple for SqlListSerializer<'a, W> {
271
271
}
272
272
}
273
273
274
+ // === ParamSerializer ===
275
+
276
+ struct ParamSerializer < ' a , W > {
277
+ writer : & ' a mut W ,
278
+ }
279
+
280
+ impl < ' a , W : Write > Serializer for ParamSerializer < ' a , W > {
281
+ type Error = SerializerError ;
282
+ type Ok = ( ) ;
283
+ type SerializeMap = Impossible ;
284
+ type SerializeSeq = SqlListSerializer < ' a , W > ;
285
+ type SerializeStruct = Impossible ;
286
+ type SerializeStructVariant = Impossible ;
287
+ type SerializeTuple = SqlListSerializer < ' a , W > ;
288
+ type SerializeTupleStruct = Impossible ;
289
+ type SerializeTupleVariant = Impossible ;
290
+
291
+ unsupported ! (
292
+ serialize_map( Option <usize >) -> Result <Impossible >,
293
+ serialize_bytes( & [ u8 ] ) ,
294
+ serialize_unit,
295
+ serialize_unit_struct( & ' static str ) ,
296
+ ) ;
297
+
298
+ forward_to_display ! (
299
+ serialize_i8( i8 ) ,
300
+ serialize_i16( i16 ) ,
301
+ serialize_i32( i32 ) ,
302
+ serialize_i64( i64 ) ,
303
+ serialize_i128( i128 ) ,
304
+ serialize_u8( u8 ) ,
305
+ serialize_u16( u16 ) ,
306
+ serialize_u32( u32 ) ,
307
+ serialize_u64( u64 ) ,
308
+ serialize_u128( u128 ) ,
309
+ serialize_f32( f32 ) ,
310
+ serialize_f64( f64 ) ,
311
+ serialize_bool( bool ) ,
312
+ ) ;
313
+
314
+ #[ inline]
315
+ fn serialize_char ( self , value : char ) -> Result {
316
+ let mut tmp = [ 0u8 ; 4 ] ;
317
+ self . serialize_str ( value. encode_utf8 ( & mut tmp) )
318
+ }
319
+
320
+ #[ inline]
321
+ fn serialize_str ( self , value : & str ) -> Result {
322
+ // ClickHouse expects strings in params to be unquoted until inside a nested type
323
+ // nested types go through serialize_seq which'll quote strings
324
+ let mut rest = value;
325
+ while let Some ( nextidx) = rest. find ( '\\' ) {
326
+ let ( before, after) = rest. split_at ( nextidx + 1 ) ;
327
+ rest = after;
328
+ self . writer . write_str ( before) ?;
329
+ self . writer . write_char ( '\\' ) ?;
330
+ }
331
+ self . writer . write_str ( rest) ?;
332
+ Ok ( ( ) )
333
+ }
334
+
335
+ #[ inline]
336
+ fn serialize_seq ( self , _len : Option < usize > ) -> Result < SqlListSerializer < ' a , W > > {
337
+ self . writer . write_char ( '[' ) ?;
338
+ Ok ( SqlListSerializer {
339
+ writer : self . writer ,
340
+ has_items : false ,
341
+ closing_char : ']' ,
342
+ } )
343
+ }
344
+
345
+ #[ inline]
346
+ fn serialize_tuple ( self , _len : usize ) -> Result < SqlListSerializer < ' a , W > > {
347
+ self . writer . write_char ( '(' ) ?;
348
+ Ok ( SqlListSerializer {
349
+ writer : self . writer ,
350
+ has_items : false ,
351
+ closing_char : ')' ,
352
+ } )
353
+ }
354
+
355
+ #[ inline]
356
+ fn serialize_some < T : Serialize + ?Sized > ( self , _value : & T ) -> Result {
357
+ _value. serialize ( self )
358
+ }
359
+
360
+ #[ inline]
361
+ fn serialize_none ( self ) -> std:: result:: Result < Self :: Ok , Self :: Error > {
362
+ self . writer . write_str ( "NULL" ) ?;
363
+ Ok ( ( ) )
364
+ }
365
+
366
+ #[ inline]
367
+ fn serialize_unit_variant (
368
+ self ,
369
+ _name : & ' static str ,
370
+ _variant_index : u32 ,
371
+ variant : & ' static str ,
372
+ ) -> Result {
373
+ escape:: string ( variant, self . writer ) ?;
374
+ Ok ( ( ) )
375
+ }
376
+
377
+ #[ inline]
378
+ fn serialize_newtype_struct < T : Serialize + ?Sized > (
379
+ self ,
380
+ _name : & ' static str ,
381
+ value : & T ,
382
+ ) -> Result {
383
+ value. serialize ( self )
384
+ }
385
+
386
+ #[ inline]
387
+ fn serialize_newtype_variant < T : Serialize + ?Sized > (
388
+ self ,
389
+ _name : & ' static str ,
390
+ _variant_index : u32 ,
391
+ _variant : & ' static str ,
392
+ _value : & T ,
393
+ ) -> Result {
394
+ Err ( SerializerError :: Unsupported ( "serialize_newtype_variant" ) )
395
+ }
396
+
397
+ #[ inline]
398
+ fn serialize_tuple_struct ( self , _name : & ' static str , _len : usize ) -> Result < Impossible > {
399
+ Err ( SerializerError :: Unsupported ( "serialize_tuple_struct" ) )
400
+ }
401
+
402
+ #[ inline]
403
+ fn serialize_tuple_variant (
404
+ self ,
405
+ _name : & ' static str ,
406
+ _variant_index : u32 ,
407
+ _variant : & ' static str ,
408
+ _len : usize ,
409
+ ) -> Result < Impossible > {
410
+ Err ( SerializerError :: Unsupported ( "serialize_tuple_variant" ) )
411
+ }
412
+
413
+ #[ inline]
414
+ fn serialize_struct ( self , _name : & ' static str , _len : usize ) -> Result < Self :: SerializeStruct > {
415
+ Err ( SerializerError :: Unsupported ( "serialize_struct" ) )
416
+ }
417
+
418
+ #[ inline]
419
+ fn serialize_struct_variant (
420
+ self ,
421
+ _name : & ' static str ,
422
+ _variant_index : u32 ,
423
+ _variant : & ' static str ,
424
+ _len : usize ,
425
+ ) -> Result < Self :: SerializeStructVariant > {
426
+ Err ( SerializerError :: Unsupported ( "serialize_struct_variant" ) )
427
+ }
428
+
429
+ #[ inline]
430
+ fn is_human_readable ( & self ) -> bool {
431
+ true
432
+ }
433
+ }
434
+
274
435
// === Public API ===
275
436
276
437
pub ( crate ) fn write_arg ( writer : & mut impl Write , value : & impl Serialize ) -> Result < ( ) , String > {
@@ -279,6 +440,12 @@ pub(crate) fn write_arg(writer: &mut impl Write, value: &impl Serialize) -> Resu
279
440
. map_err ( |err| err. to_string ( ) )
280
441
}
281
442
443
+ pub ( crate ) fn write_param ( writer : & mut impl Write , value : & impl Serialize ) -> Result < ( ) , String > {
444
+ value
445
+ . serialize ( ParamSerializer { writer } )
446
+ . map_err ( |err| err. to_string ( ) )
447
+ }
448
+
282
449
#[ cfg( test) ]
283
450
mod tests {
284
451
use super :: * ;
0 commit comments