1use rbdc::Error;
2use rbs::Value;
3use std::str::FromStr;
4use tiberius::numeric::BigDecimal;
5use tiberius::{Query, Uuid};
6
7pub trait Encode {
8 fn encode(self, q: &mut Query) -> Result<(), Error>;
9}
10
11impl Encode for Value {
12 fn encode(self, q: &mut Query) -> Result<(), Error> {
13 match self {
14 Value::Null => {
15 q.bind(Option::<Vec<u8>>::None);
16 Ok(())
17 }
18 Value::Bool(v) => {
19 q.bind(v);
20 Ok(())
21 }
22 Value::I32(v) => {
23 q.bind(v);
24 Ok(())
25 }
26 Value::I64(v) => {
27 q.bind(v);
28 Ok(())
29 }
30 Value::U32(v) => {
31 q.bind(v as i32);
32 Ok(())
33 }
34 Value::U64(v) => {
35 q.bind(v as i64);
36 Ok(())
37 }
38 Value::F32(v) => {
39 q.bind(v);
40 Ok(())
41 }
42 Value::F64(v) => {
43 q.bind(v);
44 Ok(())
45 }
46 Value::String(v) => {
47 q.bind(v);
48 Ok(())
49 }
50 Value::Binary(v) => {
51 q.bind(v);
52 Ok(())
53 }
54 Value::Array(_) => {
55 q.bind(self.to_string().into_bytes());
57 Ok(())
58 }
59 Value::Map(_) => {
60 q.bind(self.to_string().into_bytes());
62 Ok(())
63 }
64 Value::Ext(t, v) => match t {
65 "Date" => {
66 q.bind(
67 chrono::NaiveDate::from_str(v.as_str().unwrap_or_default())
68 .map_err(|e| Error::from(e.to_string()))?,
69 );
70 Ok(())
71 }
72 "DateTime" => {
73 let date = fastdate::DateTime::from_str(&v.as_str().unwrap_or_default())
74 .map_err(|e| Error::from(e.to_string()))?;
75 q.bind(
76 chrono::NaiveDateTime::from_str(&date.display(false))
77 .map_err(|e| Error::from(e.to_string()))?,
78 );
79 Ok(())
80 }
81 "Time" => {
82 q.bind(
83 chrono::NaiveTime::from_str(v.as_str().unwrap_or_default())
84 .map_err(|e| Error::from(e.to_string()))?,
85 );
86 Ok(())
87 }
88 "Decimal" => {
89 q.bind(
90 BigDecimal::from_str(&v.into_string().unwrap_or_default())
91 .map_err(|e| Error::from(e.to_string()))?,
92 );
93 Ok(())
94 }
95 "Json" => Err(Error::from("unimplemented")),
96 "Timestamp" => {
97 q.bind(v.as_i64().unwrap_or_default());
98 Ok(())
99 }
100 "Uuid" => {
101 q.bind(
102 Uuid::from_str(&v.into_string().unwrap_or_default()).unwrap_or_default(),
103 );
104 Ok(())
105 }
106 _ => Err(Error::from("unimplemented")),
107 },
108 }
109 }
110}
111
112#[cfg(test)]
113mod test {
114 use std::str::FromStr;
115
116 #[test]
117 fn test_from() {
118 let v = fastdate::DateTime::now();
119 println!("{}", v.display(false));
120 let n = chrono::NaiveDateTime::from_str(&v.display(false)).unwrap();
121 assert_eq!(
122 v.display(false),
123 n.to_string().replace(" ", "T").trim_end_matches("0")
124 );
125 }
126}