Skip to main content

voltdb_client_rust/
encode_option.rs

1use bigdecimal::BigDecimal;
2use bytebuffer::ByteBuffer;
3use chrono::{DateTime, Utc};
4
5use crate::*;
6
7impl Value for Option<bool> {
8    fn get_write_length(&self) -> i32 {
9        2
10    }
11
12    fn marshal(&self, bytebuffer: &mut ByteBuffer) {
13        bytebuffer.write_i8(TINYINT_COLUMN);
14        self.marshal_in_table(bytebuffer, TINYINT_COLUMN)
15    }
16
17    fn marshal_in_table(&self, bytebuffer: &mut ByteBuffer, _column_type: i8) {
18        match self {
19            None => bytebuffer.write_bytes(&NULL_BIT_VALUE),
20            Some(v) => v.marshal_in_table(bytebuffer, TINYINT_COLUMN),
21        }
22    }
23
24    fn to_value_string(&self) -> String {
25        format!("{:?}", self)
26    }
27
28    fn from_bytes(bs: Vec<u8>, _column: &Column) -> Result<Self, VoltError> {
29        if bs == NULL_BIT_VALUE {
30            return Ok(Option::None);
31        }
32        Ok(Some(bool::from_bytes(bs, _column)?))
33    }
34}
35
36impl Value for Option<BigDecimal> {
37    fn get_write_length(&self) -> i32 {
38        17
39    }
40
41    fn marshal(&self, bytebuffer: &mut ByteBuffer) {
42        bytebuffer.write_i8(DECIMAL_COLUMN);
43        self.marshal_in_table(bytebuffer, DECIMAL_COLUMN);
44    }
45
46    fn marshal_in_table(&self, bytebuffer: &mut ByteBuffer, _column_type: i8) {
47        match self {
48            None => bytebuffer.write_bytes(&NULL_DECIMAL),
49            Some(v) => v.marshal_in_table(bytebuffer, DECIMAL_COLUMN),
50        }
51    }
52
53    fn to_value_string(&self) -> String {
54        format!("{:?}", self)
55    }
56
57    fn from_bytes(bs: Vec<u8>, _column: &Column) -> Result<Self, VoltError>
58    where
59        Self: Sized,
60    {
61        if bs == NULL_DECIMAL {
62            return Ok(Option::None);
63        }
64        Ok(Some(BigDecimal::from_bytes(bs, _column)?))
65    }
66}
67
68impl Value for Option<i8> {
69    fn get_write_length(&self) -> i32 {
70        2
71    }
72
73    fn marshal(&self, bytebuffer: &mut ByteBuffer) {
74        bytebuffer.write_i8(TINYINT_COLUMN);
75        self.marshal_in_table(bytebuffer, TINYINT_COLUMN)
76    }
77
78    fn marshal_in_table(&self, bytebuffer: &mut ByteBuffer, _column_type: i8) {
79        match self {
80            None => bytebuffer.write_bytes(&NULL_BIT_VALUE),
81            Some(v) => v.marshal_in_table(bytebuffer, TINYINT_COLUMN),
82        }
83    }
84
85    fn to_value_string(&self) -> String {
86        format!("{:?}", self)
87    }
88
89    fn from_bytes(bs: Vec<u8>, _column: &Column) -> Result<Self, VoltError> {
90        if bs == NULL_BIT_VALUE {
91            return Ok(Option::None);
92        }
93        Ok(Some(i8::from_bytes(bs, _column)?))
94    }
95}
96
97impl Value for Option<u8> {
98    fn get_write_length(&self) -> i32 {
99        2
100    }
101
102    fn marshal(&self, bytebuffer: &mut ByteBuffer) {
103        bytebuffer.write_i8(TINYINT_COLUMN);
104        self.marshal_in_table(bytebuffer, TINYINT_COLUMN)
105    }
106
107    fn marshal_in_table(&self, bytebuffer: &mut ByteBuffer, _column_type: i8) {
108        match self {
109            None => bytebuffer.write_bytes(&NULL_BIT_VALUE),
110            Some(v) => v.marshal_in_table(bytebuffer, TINYINT_COLUMN),
111        }
112    }
113
114    fn to_value_string(&self) -> String {
115        format!("{:?}", self)
116    }
117
118    fn from_bytes(bs: Vec<u8>, _column: &Column) -> Result<Self, VoltError> {
119        if bs == NULL_BIT_VALUE {
120            return Ok(Option::None);
121        }
122        Ok(Some(u8::from_bytes(bs, _column)?))
123    }
124}
125
126impl Value for Option<i16> {
127    fn get_write_length(&self) -> i32 {
128        3
129    }
130
131    fn marshal(&self, bytebuffer: &mut ByteBuffer) {
132        bytebuffer.write_i8(SHORT_COLUMN);
133        self.marshal_in_table(bytebuffer, SHORT_COLUMN);
134    }
135
136    fn marshal_in_table(&self, bytebuffer: &mut ByteBuffer, _column_type: i8) {
137        match self {
138            None => bytebuffer.write_bytes(&NULL_SHORT_VALUE),
139            Some(v) => v.marshal_in_table(bytebuffer, SHORT_COLUMN),
140        }
141    }
142
143    fn to_value_string(&self) -> String {
144        format!("{:?}", self)
145    }
146
147    fn from_bytes(bs: Vec<u8>, _column: &Column) -> Result<Self, VoltError> {
148        if bs == NULL_SHORT_VALUE {
149            return Ok(Option::None);
150        }
151        Ok(Some(i16::from_bytes(bs, _column)?))
152    }
153}
154
155impl Value for Option<u16> {
156    fn get_write_length(&self) -> i32 {
157        3
158    }
159
160    fn marshal(&self, bytebuffer: &mut ByteBuffer) {
161        bytebuffer.write_i8(SHORT_COLUMN);
162        self.marshal_in_table(bytebuffer, SHORT_COLUMN);
163    }
164
165    fn marshal_in_table(&self, bytebuffer: &mut ByteBuffer, _column_type: i8) {
166        match self {
167            None => bytebuffer.write_bytes(&NULL_SHORT_VALUE),
168            Some(v) => v.marshal_in_table(bytebuffer, SHORT_COLUMN),
169        }
170    }
171
172    fn to_value_string(&self) -> String {
173        format!("{:?}", self)
174    }
175
176    fn from_bytes(bs: Vec<u8>, _column: &Column) -> Result<Self, VoltError> {
177        if bs == NULL_SHORT_VALUE {
178            return Ok(Option::None);
179        }
180        Ok(Some(u16::from_bytes(bs, _column)?))
181    }
182}
183
184impl Value for Option<i32> {
185    fn get_write_length(&self) -> i32 {
186        5
187    }
188
189    fn marshal(&self, bytebuffer: &mut ByteBuffer) {
190        bytebuffer.write_i8(INT_COLUMN);
191        self.marshal_in_table(bytebuffer, INT_COLUMN);
192    }
193
194    fn marshal_in_table(&self, bytebuffer: &mut ByteBuffer, _column_type: i8) {
195        match self {
196            None => bytebuffer.write_bytes(&NULL_INT_VALUE),
197            Some(v) => v.marshal_in_table(bytebuffer, INT_COLUMN),
198        }
199    }
200
201    fn to_value_string(&self) -> String {
202        format!("{:?}", self)
203    }
204
205    fn from_bytes(bs: Vec<u8>, _column: &Column) -> Result<Self, VoltError> {
206        if bs == NULL_INT_VALUE {
207            return Ok(Option::None);
208        }
209        Ok(Some(i32::from_bytes(bs, _column)?))
210    }
211}
212
213impl Value for Option<u32> {
214    fn get_write_length(&self) -> i32 {
215        5
216    }
217
218    fn marshal(&self, bytebuffer: &mut ByteBuffer) {
219        bytebuffer.write_i8(INT_COLUMN);
220        self.marshal_in_table(bytebuffer, INT_COLUMN);
221    }
222
223    fn marshal_in_table(&self, bytebuffer: &mut ByteBuffer, _column_type: i8) {
224        match self {
225            None => bytebuffer.write_bytes(&NULL_INT_VALUE),
226            Some(v) => v.marshal_in_table(bytebuffer, INT_COLUMN),
227        }
228    }
229
230    fn to_value_string(&self) -> String {
231        format!("{:?}", self)
232    }
233
234    fn from_bytes(bs: Vec<u8>, _column: &Column) -> Result<Self, VoltError> {
235        if bs == NULL_INT_VALUE {
236            return Ok(Option::None);
237        }
238        Ok(Some(u32::from_bytes(bs, _column)?))
239    }
240}
241
242impl Value for Option<i64> {
243    fn get_write_length(&self) -> i32 {
244        9
245    }
246    fn marshal(&self, bytebuffer: &mut ByteBuffer) {
247        bytebuffer.write_i8(LONG_COLUMN);
248        self.marshal_in_table(bytebuffer, LONG_COLUMN);
249    }
250
251    fn marshal_in_table(&self, bytebuffer: &mut ByteBuffer, _column_type: i8) {
252        match self {
253            None => bytebuffer.write_bytes(&NULL_LONG_VALUE),
254            Some(v) => v.marshal_in_table(bytebuffer, LONG_COLUMN),
255        }
256    }
257
258    fn to_value_string(&self) -> String {
259        format!("{:?}", self)
260    }
261
262    fn from_bytes(bs: Vec<u8>, _column: &Column) -> Result<Self, VoltError> {
263        if bs == NULL_LONG_VALUE {
264            return Ok(Option::None);
265        }
266        Ok(Some(i64::from_bytes(bs, _column)?))
267    }
268}
269
270impl Value for Option<u64> {
271    fn get_write_length(&self) -> i32 {
272        9
273    }
274
275    fn marshal(&self, bytebuffer: &mut ByteBuffer) {
276        bytebuffer.write_i8(LONG_COLUMN);
277        self.marshal_in_table(bytebuffer, LONG_COLUMN);
278    }
279
280    fn marshal_in_table(&self, bytebuffer: &mut ByteBuffer, _column_type: i8) {
281        match self {
282            None => bytebuffer.write_bytes(&NULL_LONG_VALUE),
283            Some(v) => v.marshal_in_table(bytebuffer, LONG_COLUMN),
284        }
285    }
286
287    fn to_value_string(&self) -> String {
288        format!("{:?}", self)
289    }
290
291    fn from_bytes(bs: Vec<u8>, _column: &Column) -> Result<Self, VoltError> {
292        if bs == NULL_LONG_VALUE {
293            return Ok(Option::None);
294        }
295        Ok(Some(u64::from_bytes(bs, _column)?))
296    }
297}
298
299impl Value for Option<f64> {
300    fn get_write_length(&self) -> i32 {
301        9
302    }
303
304    fn marshal(&self, bytebuffer: &mut ByteBuffer) {
305        bytebuffer.write_i8(FLOAT_COLUMN);
306        self.marshal_in_table(bytebuffer, FLOAT_COLUMN);
307    }
308
309    fn marshal_in_table(&self, bytebuffer: &mut ByteBuffer, _column_type: i8) {
310        match self {
311            None => bytebuffer.write_bytes(&NULL_FLOAT_VALUE),
312            Some(v) => v.marshal_in_table(bytebuffer, FLOAT_COLUMN),
313        }
314    }
315
316    fn to_value_string(&self) -> String {
317        format!("{:?}", self)
318    }
319
320    fn from_bytes(bs: Vec<u8>, _column: &Column) -> Result<Self, VoltError> {
321        if bs == NULL_FLOAT_VALUE {
322            return Ok(Option::None);
323        }
324        Ok(Some(f64::from_bytes(bs, _column)?))
325    }
326}
327
328impl Value for Option<String> {
329    fn get_write_length(&self) -> i32 {
330        match self {
331            None => 5,
332            Some(v) => (5 + v.len()) as i32,
333        }
334    }
335
336    fn marshal(&self, bytebuffer: &mut ByteBuffer) {
337        bytebuffer.write_i8(STRING_COLUMN);
338        match self {
339            None => bytebuffer.write_bytes(&NULL_VARCHAR),
340            Some(v) => v.marshal_in_table(bytebuffer, STRING_COLUMN),
341        }
342    }
343
344    fn marshal_in_table(&self, bytebuffer: &mut ByteBuffer, _column_type: i8) {
345        match self {
346            None => bytebuffer.write_bytes(&NULL_VARCHAR),
347            Some(v) => v.marshal_in_table(bytebuffer, STRING_COLUMN),
348        }
349    }
350
351    fn to_value_string(&self) -> String {
352        format!("{:?}", self)
353    }
354
355    fn from_bytes(bs: Vec<u8>, table_column: &Column) -> Result<Self, VoltError> {
356        match table_column.header_type {
357            STRING_COLUMN => {
358                if bs == NULL_VARCHAR {
359                    return Ok(Option::None);
360                }
361                let mut buffer = ByteBuffer::from_bytes(&bs);
362                Ok(Option::Some(buffer.read_string()?))
363            }
364            _ => {
365                let res = crate::table::VoltTable::get_value_by_idx_column(table_column, bs)?;
366                match res {
367                    Some(v) => Ok(Option::Some(v.to_value_string())),
368                    None => Ok(Option::None),
369                }
370            }
371        }
372    }
373}
374
375impl Value for Option<&str> {
376    fn get_write_length(&self) -> i32 {
377        match self {
378            None => 5,
379            Some(v) => (5 + v.len()) as i32,
380        }
381    }
382
383    fn marshal(&self, bytebuffer: &mut ByteBuffer) {
384        bytebuffer.write_i8(STRING_COLUMN);
385        match self {
386            None => bytebuffer.write_bytes(&NULL_VARCHAR),
387            Some(v) => v.marshal_in_table(bytebuffer, STRING_COLUMN),
388        }
389    }
390
391    fn marshal_in_table(&self, bytebuffer: &mut ByteBuffer, _column_type: i8) {
392        match self {
393            None => bytebuffer.write_bytes(&NULL_VARCHAR),
394            Some(v) => v.marshal_in_table(bytebuffer, STRING_COLUMN),
395        }
396    }
397
398    fn to_value_string(&self) -> String {
399        format!("{:?}", self)
400    }
401
402    fn from_bytes(_bs: Vec<u8>, _column: &Column) -> Result<Self, VoltError> {
403        todo!()
404    }
405}
406
407impl Value for Option<Vec<u8>> {
408    fn get_write_length(&self) -> i32 {
409        match self {
410            None => 5,
411            Some(v) => (5 + v.len()) as i32,
412        }
413    }
414
415    fn marshal(&self, bytebuffer: &mut ByteBuffer) {
416        bytebuffer.write_i8(VAR_BIN_COLUMN);
417        match self {
418            None => bytebuffer.write_bytes(&NULL_VARCHAR),
419            Some(v) => {
420                bytebuffer.write_bytes(v);
421            }
422        }
423    }
424
425    fn marshal_in_table(&self, bytebuffer: &mut ByteBuffer, _column_type: i8) {
426        match self {
427            None => bytebuffer.write_bytes(&NULL_VARCHAR),
428            Some(v) => {
429                bytebuffer.write_bytes(v);
430            }
431        }
432    }
433
434    fn to_value_string(&self) -> String {
435        format!("{:?}", self)
436    }
437
438    fn from_bytes(bs: Vec<u8>, _column: &Column) -> Result<Self, VoltError> {
439        if bs == NULL_VARCHAR {
440            let res: Option<Vec<u8>> = Option::None;
441            return Ok(res);
442        }
443        let mut bs = bs;
444        bs.drain(0..4);
445        Ok(Option::Some(bs))
446    }
447}
448
449impl Value for Option<DateTime<Utc>> {
450    fn get_write_length(&self) -> i32 {
451        9
452    }
453    fn marshal(&self, bytebuffer: &mut ByteBuffer) {
454        bytebuffer.write_i8(TIMESTAMP_COLUMN);
455        match self {
456            None => bytebuffer.write_bytes(&NULL_TIMESTAMP),
457            Some(v) => v.marshal_in_table(bytebuffer, TIMESTAMP_COLUMN),
458        }
459    }
460
461    fn marshal_in_table(&self, bytebuffer: &mut ByteBuffer, _column_type: i8) {
462        match self {
463            None => bytebuffer.write_bytes(&NULL_TIMESTAMP),
464            Some(v) => v.marshal_in_table(bytebuffer, TIMESTAMP_COLUMN),
465        }
466    }
467
468    fn to_value_string(&self) -> String {
469        format!("{:?}", self)
470    }
471
472    fn from_bytes(bs: Vec<u8>, _column: &Column) -> Result<Self, VoltError>
473    where
474        Self: Sized,
475    {
476        if bs == NULL_TIMESTAMP {
477            return Ok(Option::None);
478        }
479        Ok(Option::Some(DateTime::from_bytes(bs, _column)?))
480    }
481}
482
483#[cfg(test)]
484mod tests {
485    use super::*;
486    use chrono::TimeZone;
487    use std::str::FromStr;
488
489    fn make_column(name: &str, col_type: i8) -> Column {
490        Column {
491            header_name: name.to_string(),
492            header_type: col_type,
493        }
494    }
495
496    // Option<bool> tests
497    #[test]
498    fn test_option_bool_marshal_none() {
499        let val: Option<bool> = None;
500        let mut buf = ByteBuffer::new();
501        val.marshal(&mut buf);
502        assert_eq!(buf.into_vec()[0] as i8, TINYINT_COLUMN);
503    }
504
505    #[test]
506    fn test_option_bool_marshal_some() {
507        let val: Option<bool> = Some(true);
508        let mut buf = ByteBuffer::new();
509        val.marshal(&mut buf);
510        let bytes = buf.into_vec();
511        assert_eq!(bytes[0] as i8, TINYINT_COLUMN);
512        assert_eq!(bytes[1], 1);
513    }
514
515    #[test]
516    fn test_option_bool_to_value_string() {
517        let val: Option<bool> = Some(true);
518        assert!(val.to_value_string().contains("true"));
519        let val: Option<bool> = None;
520        assert!(val.to_value_string().contains("None"));
521    }
522
523    // Option<i8> tests
524    #[test]
525    fn test_option_i8_marshal_none() {
526        let val: Option<i8> = None;
527        let mut buf = ByteBuffer::new();
528        val.marshal(&mut buf);
529        let bytes = buf.into_vec();
530        assert_eq!(bytes[0] as i8, TINYINT_COLUMN);
531    }
532
533    #[test]
534    fn test_option_i8_marshal_some() {
535        let val: Option<i8> = Some(42);
536        let mut buf = ByteBuffer::new();
537        val.marshal(&mut buf);
538        let bytes = buf.into_vec();
539        assert_eq!(bytes[0] as i8, TINYINT_COLUMN);
540    }
541
542    #[test]
543    fn test_option_i8_get_write_length() {
544        let val: Option<i8> = Some(1);
545        assert_eq!(val.get_write_length(), 2);
546    }
547
548    // Option<i16> tests
549    #[test]
550    fn test_option_i16_marshal_none() {
551        let val: Option<i16> = None;
552        let mut buf = ByteBuffer::new();
553        val.marshal(&mut buf);
554        let bytes = buf.into_vec();
555        assert_eq!(bytes[0] as i8, SHORT_COLUMN);
556    }
557
558    #[test]
559    fn test_option_i16_marshal_some() {
560        let val: Option<i16> = Some(1000);
561        let mut buf = ByteBuffer::new();
562        val.marshal(&mut buf);
563        let bytes = buf.into_vec();
564        assert_eq!(bytes[0] as i8, SHORT_COLUMN);
565    }
566
567    // Option<i32> tests
568    #[test]
569    fn test_option_i32_marshal_none() {
570        let val: Option<i32> = None;
571        let mut buf = ByteBuffer::new();
572        val.marshal(&mut buf);
573        let bytes = buf.into_vec();
574        assert_eq!(bytes[0] as i8, INT_COLUMN);
575    }
576
577    #[test]
578    fn test_option_i32_marshal_some() {
579        let val: Option<i32> = Some(123456);
580        let mut buf = ByteBuffer::new();
581        val.marshal(&mut buf);
582        let bytes = buf.into_vec();
583        assert_eq!(bytes[0] as i8, INT_COLUMN);
584    }
585
586    // Option<i64> tests
587    #[test]
588    fn test_option_i64_marshal_none() {
589        let val: Option<i64> = None;
590        let mut buf = ByteBuffer::new();
591        val.marshal(&mut buf);
592        let bytes = buf.into_vec();
593        assert_eq!(bytes[0] as i8, LONG_COLUMN);
594    }
595
596    #[test]
597    fn test_option_i64_marshal_some() {
598        let val: Option<i64> = Some(9876543210);
599        let mut buf = ByteBuffer::new();
600        val.marshal(&mut buf);
601        let bytes = buf.into_vec();
602        assert_eq!(bytes[0] as i8, LONG_COLUMN);
603    }
604
605    // Option<f64> tests
606    #[test]
607    fn test_option_f64_marshal_none() {
608        let val: Option<f64> = None;
609        let mut buf = ByteBuffer::new();
610        val.marshal(&mut buf);
611        let bytes = buf.into_vec();
612        assert_eq!(bytes[0] as i8, FLOAT_COLUMN);
613    }
614
615    #[test]
616    fn test_option_f64_marshal_some() {
617        #[allow(clippy::approx_constant)]
618        let val: Option<f64> = Some(3.14159);
619        let mut buf = ByteBuffer::new();
620        val.marshal(&mut buf);
621        let bytes = buf.into_vec();
622        assert_eq!(bytes[0] as i8, FLOAT_COLUMN);
623    }
624
625    // Option<String> tests
626    #[test]
627    fn test_option_string_marshal_none() {
628        let val: Option<String> = None;
629        let mut buf = ByteBuffer::new();
630        val.marshal(&mut buf);
631        let bytes = buf.into_vec();
632        assert_eq!(bytes[0] as i8, STRING_COLUMN);
633    }
634
635    #[test]
636    fn test_option_string_marshal_some() {
637        let val: Option<String> = Some("hello".to_string());
638        let mut buf = ByteBuffer::new();
639        val.marshal(&mut buf);
640        let bytes = buf.into_vec();
641        assert_eq!(bytes[0] as i8, STRING_COLUMN);
642    }
643
644    #[test]
645    fn test_option_string_get_write_length() {
646        let val: Option<String> = None;
647        assert_eq!(val.get_write_length(), 5);
648        let val: Option<String> = Some("test".to_string());
649        assert_eq!(val.get_write_length(), 5 + 4);
650    }
651
652    // Option<Vec<u8>> tests
653    #[test]
654    fn test_option_vec_u8_marshal_none() {
655        let val: Option<Vec<u8>> = None;
656        let mut buf = ByteBuffer::new();
657        val.marshal(&mut buf);
658        let bytes = buf.into_vec();
659        assert_eq!(bytes[0] as i8, VAR_BIN_COLUMN);
660    }
661
662    #[test]
663    fn test_option_vec_u8_marshal_some() {
664        let val: Option<Vec<u8>> = Some(vec![1, 2, 3, 4]);
665        let mut buf = ByteBuffer::new();
666        val.marshal(&mut buf);
667        let bytes = buf.into_vec();
668        assert_eq!(bytes[0] as i8, VAR_BIN_COLUMN);
669    }
670
671    // Option<BigDecimal> tests
672    #[test]
673    fn test_option_decimal_marshal_none() {
674        let val: Option<BigDecimal> = None;
675        let mut buf = ByteBuffer::new();
676        val.marshal(&mut buf);
677        let bytes = buf.into_vec();
678        assert_eq!(bytes[0] as i8, DECIMAL_COLUMN);
679    }
680
681    #[test]
682    fn test_option_decimal_marshal_some() {
683        let val: Option<BigDecimal> = Some(BigDecimal::from_str("123.45").unwrap());
684        let mut buf = ByteBuffer::new();
685        val.marshal(&mut buf);
686        let bytes = buf.into_vec();
687        assert_eq!(bytes[0] as i8, DECIMAL_COLUMN);
688    }
689
690    // Option<DateTime<Utc>> tests
691    #[test]
692    fn test_option_datetime_marshal_none() {
693        let val: Option<DateTime<Utc>> = None;
694        let mut buf = ByteBuffer::new();
695        val.marshal(&mut buf);
696        let bytes = buf.into_vec();
697        assert_eq!(bytes[0] as i8, TIMESTAMP_COLUMN);
698    }
699
700    #[test]
701    fn test_option_datetime_marshal_some() {
702        let val: Option<DateTime<Utc>> = Some(Utc.timestamp_millis_opt(1000000).unwrap());
703        let mut buf = ByteBuffer::new();
704        val.marshal(&mut buf);
705        let bytes = buf.into_vec();
706        assert_eq!(bytes[0] as i8, TIMESTAMP_COLUMN);
707    }
708
709    // Round-trip tests
710    #[test]
711    fn test_option_i32_roundtrip_some() {
712        let col = make_column("test", INT_COLUMN);
713        let original: Option<i32> = Some(42);
714        let mut buf = ByteBuffer::new();
715        original.marshal_in_table(&mut buf, INT_COLUMN);
716        let bytes = buf.into_vec();
717        let result: Option<i32> = Option::from_bytes(bytes, &col).unwrap();
718        assert_eq!(result, original);
719    }
720
721    #[test]
722    fn test_option_i32_roundtrip_none() {
723        let col = make_column("test", INT_COLUMN);
724        let original: Option<i32> = None;
725        let mut buf = ByteBuffer::new();
726        original.marshal_in_table(&mut buf, INT_COLUMN);
727        let bytes = buf.into_vec();
728        let result: Option<i32> = Option::from_bytes(bytes, &col).unwrap();
729        assert_eq!(result, original);
730    }
731
732    #[test]
733    fn test_option_string_roundtrip_some() {
734        let col = make_column("test", STRING_COLUMN);
735        let original: Option<String> = Some("hello world".to_string());
736        let mut buf = ByteBuffer::new();
737        original.marshal_in_table(&mut buf, STRING_COLUMN);
738        let bytes = buf.into_vec();
739        let result: Option<String> = Option::from_bytes(bytes, &col).unwrap();
740        assert_eq!(result, original);
741    }
742
743    // marshal_in_table tests
744    #[test]
745    fn test_option_i64_marshal_in_table_none() {
746        let val: Option<i64> = None;
747        let mut buf = ByteBuffer::new();
748        val.marshal_in_table(&mut buf, LONG_COLUMN);
749        assert_eq!(buf.into_vec(), NULL_LONG_VALUE.to_vec());
750    }
751
752    #[test]
753    fn test_option_str_marshal() {
754        let val: Option<&str> = Some("test");
755        let mut buf = ByteBuffer::new();
756        val.marshal(&mut buf);
757        let bytes = buf.into_vec();
758        assert_eq!(bytes[0] as i8, STRING_COLUMN);
759    }
760
761    #[test]
762    fn test_option_str_marshal_none() {
763        let val: Option<&str> = None;
764        let mut buf = ByteBuffer::new();
765        val.marshal(&mut buf);
766        let bytes = buf.into_vec();
767        assert_eq!(bytes[0] as i8, STRING_COLUMN);
768    }
769
770    // Unsigned types tests
771    #[test]
772    fn test_option_u8_marshal() {
773        let val: Option<u8> = Some(255);
774        let mut buf = ByteBuffer::new();
775        val.marshal(&mut buf);
776        assert_eq!(buf.into_vec()[0] as i8, TINYINT_COLUMN);
777    }
778
779    #[test]
780    fn test_option_u16_marshal() {
781        let val: Option<u16> = Some(65535);
782        let mut buf = ByteBuffer::new();
783        val.marshal(&mut buf);
784        assert_eq!(buf.into_vec()[0] as i8, SHORT_COLUMN);
785    }
786
787    #[test]
788    fn test_option_u32_marshal() {
789        let val: Option<u32> = Some(4294967295);
790        let mut buf = ByteBuffer::new();
791        val.marshal(&mut buf);
792        assert_eq!(buf.into_vec()[0] as i8, INT_COLUMN);
793    }
794
795    #[test]
796    fn test_option_u64_marshal() {
797        let val: Option<u64> = Some(18446744073709551615);
798        let mut buf = ByteBuffer::new();
799        val.marshal(&mut buf);
800        assert_eq!(buf.into_vec()[0] as i8, LONG_COLUMN);
801    }
802}