Skip to main content

odbc/statement/
types.rs

1use ffi;
2use std::slice::from_raw_parts;
3use std::mem::{size_of, transmute};
4use std::ffi::CString;
5use std::borrow::Cow::{Borrowed, Owned};
6
7pub struct EncodedValue {
8    pub buf: Option<Vec<u8>>,
9}
10
11impl EncodedValue {
12    pub fn new(buf: Option<Vec<u8>>) -> Self {
13        Self { buf }
14    }
15
16    pub fn has_value(&self) -> bool {
17        self.buf.is_some()
18    }
19
20    pub fn column_size(&self) -> ffi::SQLULEN {
21        if let Some(buf) = &self.buf {
22            buf.len() as ffi::SQLULEN
23        } else {
24            0
25        }
26    }
27
28    pub fn value_ptr(&self) -> ffi::SQLPOINTER {
29        if let Some(buf) = &self.buf {
30            buf.as_ptr() as *const Self as ffi::SQLPOINTER
31        } else {
32            0 as *const Self as ffi::SQLPOINTER
33        }
34    }
35}
36
37pub unsafe trait OdbcType<'a>: Sized {
38    fn sql_data_type() -> ffi::SqlDataType;
39    fn c_data_type() -> ffi::SqlCDataType;
40    fn convert(_: &'a [u8]) -> Self;
41    fn column_size(&self) -> ffi::SQLULEN;
42    fn null_bytes_count() -> usize {
43        0
44    }
45    fn value_ptr(&self) -> ffi::SQLPOINTER;
46    fn decimal_digits(&self) -> ffi::SQLSMALLINT {
47        0
48    }
49    fn encoded_value(&self) -> EncodedValue;
50}
51
52unsafe impl<'a> OdbcType<'a> for &'a[u8] {
53    fn sql_data_type() -> ffi::SqlDataType {
54        ffi::SQL_EXT_VARBINARY
55    }
56    fn c_data_type() -> ffi::SqlCDataType {
57        ffi::SQL_C_BINARY
58    }
59
60    fn convert(buffer: &'a [u8]) -> Self {
61        buffer
62    }
63
64    fn column_size(&self) -> ffi::SQLULEN {
65        self.len() as ffi::SQLULEN
66    }
67
68    fn value_ptr(&self) -> ffi::SQLPOINTER {
69        self.as_ptr() as *const Self as ffi::SQLPOINTER
70    }
71
72    fn encoded_value(&self) -> EncodedValue {
73        EncodedValue::new(None)
74    }
75}
76
77unsafe impl<'a> OdbcType<'a> for Vec<u8> {
78    fn sql_data_type() -> ffi::SqlDataType {
79        ffi::SQL_EXT_VARBINARY
80    }
81    fn c_data_type() -> ffi::SqlCDataType {
82        ffi::SQL_C_BINARY
83    }
84
85    fn convert(buffer: &'a [u8]) -> Self {
86        buffer.to_vec()
87    }
88
89    fn column_size(&self) -> ffi::SQLULEN {
90        self.len() as ffi::SQLULEN
91    }
92
93    fn value_ptr(&self) -> ffi::SQLPOINTER {
94        self.as_ptr() as *const Self as ffi::SQLPOINTER
95    }
96
97    fn encoded_value(&self) -> EncodedValue {
98        EncodedValue::new(None)
99    }
100}
101
102unsafe impl<'a> OdbcType<'a> for &'a[u16] {
103    fn sql_data_type() -> ffi::SqlDataType {
104        ffi::SQL_EXT_WVARCHAR
105    }
106    fn c_data_type() -> ffi::SqlCDataType {
107        ffi::SQL_C_WCHAR
108    }
109
110    fn convert(buffer: &'a [u8]) -> Self {
111        unsafe { from_raw_parts(buffer.as_ptr() as *const u16, buffer.len() / 2) }
112    }
113
114    fn column_size(&self) -> ffi::SQLULEN {
115        (self.len() * 2) as ffi::SQLULEN
116    }
117
118    fn null_bytes_count() -> usize {
119        2
120    }
121
122    fn value_ptr(&self) -> ffi::SQLPOINTER {
123        self.as_ptr() as *const Self as ffi::SQLPOINTER
124    }
125
126    fn encoded_value(&self) -> EncodedValue {
127        EncodedValue::new(None)
128    }
129}
130
131unsafe impl<'a> OdbcType<'a> for Vec<u16> {
132    fn sql_data_type() -> ffi::SqlDataType {
133        ffi::SQL_EXT_WVARCHAR
134    }
135    fn c_data_type() -> ffi::SqlCDataType {
136        ffi::SQL_C_WCHAR
137    }
138
139    fn convert(buffer: &'a [u8]) -> Self {
140        let buffer = unsafe { from_raw_parts(buffer.as_ptr() as *const u16, buffer.len() / 2) };
141        buffer.to_vec()
142    }
143
144    fn column_size(&self) -> ffi::SQLULEN {
145        (self.len() * 2) as ffi::SQLULEN
146    }
147
148    fn null_bytes_count() -> usize {
149        2
150    }
151
152    fn value_ptr(&self) -> ffi::SQLPOINTER {
153        self.as_ptr() as *const Self as ffi::SQLPOINTER
154    }
155    
156    fn encoded_value(&self) -> EncodedValue {
157        EncodedValue::new(None)
158    }
159}
160
161unsafe impl<'a> OdbcType<'a> for CString {
162    fn sql_data_type() -> ffi::SqlDataType {
163        ffi::SQL_VARCHAR
164    }
165    fn c_data_type() -> ffi::SqlCDataType {
166        ffi::SQL_C_CHAR
167    }
168
169    fn convert(buffer: &'a [u8]) -> Self {
170        CString::new(buffer).unwrap()
171    }
172
173    fn column_size(&self) -> ffi::SQLULEN {
174        self.as_bytes().len() as ffi::SQLULEN
175    }
176
177    fn value_ptr(&self) -> ffi::SQLPOINTER {
178        self.as_bytes().as_ptr() as *const Self as ffi::SQLPOINTER
179    }
180
181    fn null_bytes_count() -> usize {
182        1
183    }
184    
185    fn encoded_value(&self) -> EncodedValue {
186        EncodedValue::new(None)
187    }
188}
189
190unsafe impl<'a> OdbcType<'a> for String {
191    fn sql_data_type() -> ffi::SqlDataType {
192        ffi::SQL_VARCHAR
193    }
194    fn c_data_type() -> ffi::SqlCDataType {
195        ffi::SQL_C_CHAR
196    }
197
198    fn convert(buffer: &'a [u8]) -> Self {
199        unsafe { ::environment::DB_ENCODING }.decode(buffer).0.to_string()
200    }
201
202    fn column_size(&self) -> ffi::SQLULEN {
203        unsafe { ::environment::DB_ENCODING }.encode(&self).0.len() as ffi::SQLULEN
204    }
205
206    fn value_ptr(&self) -> ffi::SQLPOINTER {
207        unsafe { ::environment::DB_ENCODING }.encode(&self).0.as_ptr() as *const Self as ffi::SQLPOINTER
208    }
209
210    fn null_bytes_count() -> usize {
211        1
212    }
213    
214    fn encoded_value(&self) -> EncodedValue {
215        EncodedValue::new(Some(unsafe { ::environment::DB_ENCODING }.encode(&self).0.to_vec()))
216    }
217}
218
219unsafe impl<'a> OdbcType<'a> for &'a str {
220    fn sql_data_type() -> ffi::SqlDataType {
221        ffi::SQL_VARCHAR
222    }
223    fn c_data_type() -> ffi::SqlCDataType {
224        ffi::SQL_C_CHAR
225    }
226
227    fn convert(buffer: &'a [u8]) -> Self {
228        let cow = unsafe { ::environment::DB_ENCODING }.decode(buffer).0;
229        match cow {
230            Borrowed(strref) => strref,
231            Owned(_string) => panic!("Couldn't convert data to `&str`. Try `String` or `Cow<str>` instead."),
232        }
233    }
234
235    fn column_size(&self) -> ffi::SQLULEN {
236        unsafe { ::environment::DB_ENCODING }.encode(self).0.len() as ffi::SQLULEN
237    }
238
239    fn value_ptr(&self) -> ffi::SQLPOINTER {
240        unsafe { ::environment::DB_ENCODING }.encode(self).0.as_ptr() as *const Self as ffi::SQLPOINTER
241    }
242
243    fn null_bytes_count() -> usize {
244        1
245    }
246    
247    fn encoded_value(&self) -> EncodedValue {
248        EncodedValue::new(Some(unsafe { ::environment::DB_ENCODING }.encode(&self).0.to_vec()))
249    }
250}
251
252unsafe impl<'a> OdbcType<'a> for ::std::borrow::Cow<'a, str> {
253    fn sql_data_type() -> ffi::SqlDataType {
254        ffi::SQL_VARCHAR
255    }
256    fn c_data_type() -> ffi::SqlCDataType {
257        ffi::SQL_C_CHAR
258    }
259
260    fn convert(buffer: &'a [u8]) -> Self {
261        unsafe {::environment::DB_ENCODING.decode(buffer).0}
262    }
263
264    fn column_size(&self) -> ffi::SQLULEN {
265        unsafe { ::environment::DB_ENCODING }.encode(self).0.len() as ffi::SQLULEN
266    }
267
268    fn value_ptr(&self) -> ffi::SQLPOINTER {
269        unsafe { ::environment::DB_ENCODING }.encode(self).0.as_ptr() as *const Self as ffi::SQLPOINTER
270    }
271
272    fn null_bytes_count() -> usize {
273        1
274    }
275    
276    fn encoded_value(&self) -> EncodedValue {
277        EncodedValue::new(Some(unsafe { ::environment::DB_ENCODING }.encode(self).0.to_vec()))
278    }
279}
280
281fn convert_primitive<T>(buf: &[u8]) -> T
282where
283    T: Copy,
284{
285    unsafe { from_raw_parts(buf.as_ptr() as *const T, 1)[0] }
286}
287
288unsafe impl<'a> OdbcType<'a> for u8 {
289    fn sql_data_type() -> ffi::SqlDataType {
290        ffi::SQL_SMALLINT
291    }
292    fn c_data_type() -> ffi::SqlCDataType {
293        ffi::SQL_C_UTINYINT
294    }
295
296    fn convert(buffer: &'a [u8]) -> Self {
297        convert_primitive(buffer)
298    }
299
300    fn column_size(&self) -> ffi::SQLULEN {
301        size_of::<Self>() as ffi::SQLULEN
302    }
303    fn value_ptr(&self) -> ffi::SQLPOINTER {
304        self as *const Self as ffi::SQLPOINTER
305    }
306    
307    fn encoded_value(&self) -> EncodedValue {
308        EncodedValue::new(None)
309    }
310}
311
312unsafe impl<'a> OdbcType<'a> for i8 {
313    fn sql_data_type() -> ffi::SqlDataType {
314        ffi::SQL_SMALLINT
315    }
316    fn c_data_type() -> ffi::SqlCDataType {
317        ffi::SQL_C_STINYINT
318    }
319
320    fn convert(buffer: &'a [u8]) -> Self {
321        convert_primitive(buffer)
322    }
323
324    fn column_size(&self) -> ffi::SQLULEN {
325        size_of::<Self>() as ffi::SQLULEN
326    }
327    fn value_ptr(&self) -> ffi::SQLPOINTER {
328        self as *const Self as ffi::SQLPOINTER
329    }
330    
331    fn encoded_value(&self) -> EncodedValue {
332        EncodedValue::new(None)
333    }
334}
335
336unsafe impl<'a> OdbcType<'a> for i16 {
337    fn sql_data_type() -> ffi::SqlDataType {
338        ffi::SQL_SMALLINT
339    }
340    fn c_data_type() -> ffi::SqlCDataType {
341        ffi::SQL_C_SSHORT
342    }
343
344    fn convert(buffer: &'a [u8]) -> Self {
345        convert_primitive(buffer)
346    }
347
348    fn column_size(&self) -> ffi::SQLULEN {
349        size_of::<Self>() as ffi::SQLULEN
350    }
351    fn value_ptr(&self) -> ffi::SQLPOINTER {
352        self as *const Self as ffi::SQLPOINTER
353    }
354    
355    fn encoded_value(&self) -> EncodedValue {
356        EncodedValue::new(None)
357    }
358}
359
360unsafe impl<'a> OdbcType<'a> for u16 {
361    fn sql_data_type() -> ffi::SqlDataType {
362        ffi::SQL_SMALLINT
363    }
364    fn c_data_type() -> ffi::SqlCDataType {
365        ffi::SQL_C_USHORT
366    }
367
368    fn convert(buffer: &'a [u8]) -> Self {
369        convert_primitive(buffer)
370    }
371
372    fn column_size(&self) -> ffi::SQLULEN {
373        size_of::<Self>() as ffi::SQLULEN
374    }
375    fn value_ptr(&self) -> ffi::SQLPOINTER {
376        self as *const Self as ffi::SQLPOINTER
377    }
378    
379    fn encoded_value(&self) -> EncodedValue {
380        EncodedValue::new(None)
381    }
382}
383
384unsafe impl<'a> OdbcType<'a> for i32 {
385    fn sql_data_type() -> ffi::SqlDataType {
386        ffi::SQL_INTEGER
387    }
388    fn c_data_type() -> ffi::SqlCDataType {
389        ffi::SQL_C_SLONG
390    }
391
392    fn convert(buffer: &'a [u8]) -> Self {
393        convert_primitive(buffer)
394    }
395
396    fn column_size(&self) -> ffi::SQLULEN {
397        size_of::<Self>() as ffi::SQLULEN
398    }
399    fn value_ptr(&self) -> ffi::SQLPOINTER {
400        self as *const Self as ffi::SQLPOINTER
401    }
402    
403    fn encoded_value(&self) -> EncodedValue {
404        EncodedValue::new(None)
405    }
406}
407
408unsafe impl<'a> OdbcType<'a> for u32 {
409    fn sql_data_type() -> ffi::SqlDataType {
410        ffi::SQL_INTEGER
411    }
412    fn c_data_type() -> ffi::SqlCDataType {
413        ffi::SQL_C_ULONG
414    }
415
416    fn convert(buffer: &'a [u8]) -> Self {
417        convert_primitive(buffer)
418    }
419
420    fn column_size(&self) -> ffi::SQLULEN {
421        size_of::<Self>() as ffi::SQLULEN
422    }
423    fn value_ptr(&self) -> ffi::SQLPOINTER {
424        self as *const Self as ffi::SQLPOINTER
425    }
426    
427    fn encoded_value(&self) -> EncodedValue {
428        EncodedValue::new(None)
429    }
430}
431
432unsafe impl<'a> OdbcType<'a> for i64 {
433    fn sql_data_type() -> ffi::SqlDataType {
434        ffi::SQL_EXT_BIGINT
435    }
436    fn c_data_type() -> ffi::SqlCDataType {
437        ffi::SQL_C_SBIGINT
438    }
439
440    fn convert(buffer: &'a [u8]) -> Self {
441        convert_primitive(buffer)
442    }
443
444    fn column_size(&self) -> ffi::SQLULEN {
445        size_of::<Self>() as ffi::SQLULEN
446    }
447    fn value_ptr(&self) -> ffi::SQLPOINTER {
448        self as *const Self as ffi::SQLPOINTER
449    }
450    
451    fn encoded_value(&self) -> EncodedValue {
452        EncodedValue::new(None)
453    }
454}
455
456unsafe impl<'a> OdbcType<'a> for u64 {
457    fn sql_data_type() -> ffi::SqlDataType {
458        ffi::SQL_EXT_BIGINT
459    }
460    fn c_data_type() -> ffi::SqlCDataType {
461        ffi::SQL_C_UBIGINT
462    }
463
464    fn convert(buffer: &'a [u8]) -> Self {
465        convert_primitive(buffer)
466    }
467
468    fn column_size(&self) -> ffi::SQLULEN {
469        size_of::<Self>() as ffi::SQLULEN
470    }
471    fn value_ptr(&self) -> ffi::SQLPOINTER {
472        self as *const Self as ffi::SQLPOINTER
473    }
474    
475    fn encoded_value(&self) -> EncodedValue {
476        EncodedValue::new(None)
477    }
478}
479
480unsafe impl<'a> OdbcType<'a> for f32 {
481    fn sql_data_type() -> ffi::SqlDataType {
482        ffi::SQL_FLOAT
483    }
484    fn c_data_type() -> ffi::SqlCDataType {
485        ffi::SQL_C_FLOAT
486    }
487
488    fn convert(buffer: &'a [u8]) -> Self {
489        convert_primitive(buffer)
490    }
491
492    fn column_size(&self) -> ffi::SQLULEN {
493        size_of::<Self>() as ffi::SQLULEN
494    }
495    fn value_ptr(&self) -> ffi::SQLPOINTER {
496        self as *const Self as ffi::SQLPOINTER
497    }
498    
499    fn encoded_value(&self) -> EncodedValue {
500        EncodedValue::new(None)
501    }
502}
503
504unsafe impl<'a> OdbcType<'a> for f64 {
505    fn sql_data_type() -> ffi::SqlDataType {
506        ffi::SQL_DOUBLE
507    }
508    fn c_data_type() -> ffi::SqlCDataType {
509        ffi::SQL_C_DOUBLE
510    }
511
512    fn convert(buffer: &'a [u8]) -> Self {
513        convert_primitive(buffer)
514    }
515
516    fn column_size(&self) -> ffi::SQLULEN {
517        size_of::<Self>() as ffi::SQLULEN
518    }
519    fn value_ptr(&self) -> ffi::SQLPOINTER {
520        self as *const Self as ffi::SQLPOINTER
521    }
522    
523    fn encoded_value(&self) -> EncodedValue {
524        EncodedValue::new(None)
525    }
526}
527
528unsafe impl<'a> OdbcType<'a> for bool {
529    fn sql_data_type() -> ffi::SqlDataType {
530        ffi::SQL_EXT_BIT
531    }
532    fn c_data_type() -> ffi::SqlCDataType {
533        ffi::SQL_C_BIT
534    }
535
536    fn convert(buffer: &'a [u8]) -> Self {
537        assert!(buffer.len() == 1);
538        buffer[0] > 0
539    }
540
541    fn column_size(&self) -> ffi::SQLULEN {
542        1 as ffi::SQLULEN
543    }
544    fn value_ptr(&self) -> ffi::SQLPOINTER {
545        self as *const Self as ffi::SQLPOINTER
546    }
547    
548    fn encoded_value(&self) -> EncodedValue {
549        EncodedValue::new(None)
550    }
551}
552
553pub type SqlDate = ffi::SQL_DATE_STRUCT;
554
555unsafe impl<'a> OdbcType<'a> for SqlDate {
556    fn sql_data_type() -> ffi::SqlDataType {
557        ffi::SQL_DATE
558    }
559    fn c_data_type() -> ffi::SqlCDataType {
560        ffi::SQL_C_DATE
561    }
562
563    fn convert(buffer: &'a [u8]) -> Self {
564        assert_eq!(buffer.len(), size_of::<Self>());
565        unsafe {
566            let ptr = buffer.as_ptr() as *const [u8; size_of::<Self>()];
567            transmute(*ptr)
568        }
569    }
570
571    fn column_size(&self) -> ffi::SQLULEN {
572        size_of::<Self>() as ffi::SQLULEN
573    }
574    fn value_ptr(&self) -> ffi::SQLPOINTER {
575        self as *const Self as ffi::SQLPOINTER
576    }
577    
578    fn encoded_value(&self) -> EncodedValue {
579        EncodedValue::new(None)
580    }
581}
582
583pub type SqlTime = ffi::SQL_TIME_STRUCT;
584
585unsafe impl<'a> OdbcType<'a> for SqlTime {
586    fn sql_data_type() -> ffi::SqlDataType {
587        ffi::SQL_TIME
588    }
589    fn c_data_type() -> ffi::SqlCDataType {
590        ffi::SQL_C_TIME
591    }
592
593    fn convert(buffer: &'a [u8]) -> Self {
594        assert_eq!(buffer.len(), size_of::<Self>());
595        unsafe {
596            let ptr = buffer.as_ptr() as *const [u8; size_of::<Self>()];
597            transmute(*ptr)
598        }
599    }
600
601    fn column_size(&self) -> ffi::SQLULEN {
602        size_of::<Self>() as ffi::SQLULEN
603    }
604    fn value_ptr(&self) -> ffi::SQLPOINTER {
605        self as *const Self as ffi::SQLPOINTER
606    }
607    
608    fn encoded_value(&self) -> EncodedValue {
609        EncodedValue::new(None)
610    }
611}
612
613pub type SqlTimestamp = ffi::SQL_TIMESTAMP_STRUCT;
614
615unsafe impl<'a> OdbcType<'a> for SqlTimestamp {
616    fn sql_data_type() -> ffi::SqlDataType {
617        ffi::SQL_TIMESTAMP
618    }
619    fn c_data_type() -> ffi::SqlCDataType {
620        ffi::SQL_C_TYPE_TIMESTAMP
621    }
622
623    fn convert(buffer: &'a [u8]) -> Self {
624        assert_eq!(buffer.len(), size_of::<Self>());
625        unsafe {
626            let ptr = buffer.as_ptr() as *const [u8; size_of::<Self>()];
627            transmute(*ptr)
628        }
629    }
630
631    fn column_size(&self) -> ffi::SQLULEN {
632        size_of::<Self>() as ffi::SQLULEN
633    }
634    fn value_ptr(&self) -> ffi::SQLPOINTER {
635        self as *const Self as ffi::SQLPOINTER
636    }
637    
638    fn encoded_value(&self) -> EncodedValue {
639        EncodedValue::new(None)
640    }
641}
642
643pub type SqlSsTime2 = ffi::SQL_SS_TIME2_STRUCT;
644
645unsafe impl<'a> OdbcType<'a> for SqlSsTime2 {
646    fn sql_data_type() -> ffi::SqlDataType {
647        ffi::SQL_EXT_VARBINARY
648    }
649    fn c_data_type() -> ffi::SqlCDataType {
650        // NOTE: ODBC 3.5 and earlier
651        ffi::SQL_C_BINARY
652    }
653
654    fn convert(buffer: &'a [u8]) -> Self {
655        assert_eq!(buffer.len(), size_of::<Self>());
656        unsafe {
657            let ptr = buffer.as_ptr() as *const [u8; size_of::<Self>()];
658            transmute(*ptr)
659        }
660    }
661
662    fn column_size(&self) -> ffi::SQLULEN {
663        size_of::<Self>() as ffi::SQLULEN
664    }
665    fn value_ptr(&self) -> ffi::SQLPOINTER {
666        self as *const Self as ffi::SQLPOINTER
667    }
668    
669    fn encoded_value(&self) -> EncodedValue {
670        EncodedValue::new(None)
671    }
672}
673
674unsafe impl<'a, T> OdbcType<'a> for Option<T> where T: OdbcType<'a> {
675    fn sql_data_type() -> ffi::SqlDataType {
676        T::sql_data_type()
677    }
678
679    fn c_data_type() -> ffi::SqlCDataType {
680        T::c_data_type()
681    }
682
683    fn convert(buffer: &'a [u8]) -> Self {
684        Some(T::convert(buffer))
685    }
686
687    fn column_size(&self) -> ffi::SQLULEN {
688        if let Some(t) = self {
689            t.column_size()
690        } else {
691            0
692        }
693    }
694    fn value_ptr(&self) -> ffi::SQLPOINTER {
695        if let Some(t) = self {
696            t.value_ptr()
697        } else {
698            0 as *const Self as ffi::SQLPOINTER
699        }
700    }
701
702    fn null_bytes_count() -> usize {
703        T::null_bytes_count()
704    }
705    
706    fn encoded_value(&self) -> EncodedValue {
707        EncodedValue::new(None)
708    }
709}
710
711
712mod test {
713    // use environment::create_environment_v3_with_os_db_encoding;
714    use super::*;
715    use std::collections::HashSet;
716    use std::borrow::Cow;
717
718    #[test]
719    fn encoded_value_test() {
720        let mut checker = HashSet::new();
721        let mut encoded_values = Vec::new();
722
723        // let _ = create_environment_v3_with_os_db_encoding("utf8", "sjis");
724
725        //string test
726        for i in 0..10 {
727            for h in 0..10 {
728                let string_value = format!("{}{}", i, h);
729                // println!("org value => {}    address => {:?}", string_value, string_value.value_ptr());
730
731                let enc = string_value.encoded_value();
732                // println!("{} {:?}", enc.column_size(), enc.buf);
733                if checker.len() == 0 || !checker.contains(&enc.value_ptr()) {
734                    checker.insert(enc.value_ptr());
735                    encoded_values.push(enc);
736                } else {
737                    panic!("same address occur!");
738                }
739            }
740        }
741        checker.clear();
742        encoded_values.clear();
743
744        //&str test
745        for i in 0..10 {
746            for h in 0..10 {
747                let str_value: &str = &format!("{}{}", i, h);
748                // println!("org value => {}    address => {:?}", str_value, str_value.value_ptr());
749
750                let enc = str_value.encoded_value();
751                if checker.len() == 0 || !checker.contains(&enc.value_ptr()) {
752                    checker.insert(enc.value_ptr());
753                    encoded_values.push(enc);
754                } else {
755                    panic!("same address occur!");
756                }
757            }
758        }
759        checker.clear();
760        encoded_values.clear();
761
762        //Cow<str> test
763        for i in 0..10 {
764            for h in 0..10 {
765                let cow_value: Cow<str> = Cow::from(format!("{}{}", i, h));
766                // println!("org value => {}    address => {:?}", cow_value, cow_value.value_ptr());
767
768                let enc = cow_value.encoded_value();
769                if checker.len() == 0 || !checker.contains(&enc.value_ptr()) {
770                    checker.insert(enc.value_ptr());
771                    encoded_values.push(enc);
772                } else {
773                    panic!("same address occur!");
774                }
775            }
776        }
777        checker.clear();
778        encoded_values.clear();
779
780    }
781}