1use log::info;
3use rbson::Bson;
4use serde::de::DeserializeOwned;
5
6use crate::types::Format;
7use crate::Error;
8use crate::Error::E;
9
10pub fn decode<T: ?Sized>(datas: rbson::Array) -> Result<T, crate::Error>
15where
16 T: DeserializeOwned,
17{
18 let type_name = std::any::type_name::<T>();
19 let bs = Bson::Array(datas);
21 #[cfg(feature = "debug_mode")]
22 {
23 println!("[mybatis] [debug_mode] [bson] {} => {}", type_name, bs);
24 #[cfg(feature = "format_bson")]
25 println!(
26 "[mybatis] [debug_mode] [format] {} => {}",
27 type_name,
28 bs.as_array().unwrap().do_format()
29 );
30 }
31 let mut datas = vec![];
32 match bs {
33 Bson::Array(arr) => {
34 datas = arr;
35 }
36 _ => {}
37 }
38 match type_name {
40 "core::option::Option<i8>" | "core::option::Option<i16>" | "core::option::Option<i32>" | "core::option::Option<i64>" |
42 "core::option::Option<u8>" | "core::option::Option<u16>" | "core::option::Option<u32>" | "core::option::Option<u64>" |
43 "core::option::Option<f32>" | "core::option::Option<f64>" |
44 "core::option::Option<serde_json::number::Number>" |
45 "core::option::Option<rbson::Bson::Int64>" | "core::option::Option<rbson::Bson::Int32>" | "core::option::Option<rbson::Bson::Double>" |
46 "core::option::Option<bigdecimal::BigDecimal>" |
47 "core::option::Option<bool>" |
48 "core::option::Option<alloc::string::String>" |
49 "i8" | "i16" | "i32" | "i64" |
51 "u8" | "u16" | "u32" | "u64" |
52 "f32" | "f64" |
53 "serde_json::number::Number" |
54 "rbson::Bson::Int64" | "rbson::Bson::Int32" | "rbson::Bson::Double" |
55 "bigdecimal::BigDecimal" |
56 "bool" |
57 "alloc::string::String" => {
58 return Ok(try_decode_doc(type_name, &mut datas)?);
59 }
60 _ => {}
61 }
62 let is_array: Result<T, rbson::de::Error> = rbson::from_bson(rbson::Bson::Array(vec![]));
64 if is_array.is_ok() {
65 Ok(rbson::from_bson(Bson::Array(datas))?)
67 } else {
68 Ok(try_decode_doc(type_name, &mut datas)?)
69 }
70}
71
72pub fn try_decode_doc<T>(type_name: &str, datas: &mut Vec<Bson>) -> Result<T, crate::Error>
74where
75 T: DeserializeOwned,
76{
77 if datas.len() > 1 {
79 return Result::Err(Error::from(format!(
80 "[mybatis] rows.rows_affected > 1,but decode one type ({})!",
81 type_name
82 )));
83 }
84 if datas.is_empty() {
86 return Ok(rbson::from_bson::<T>(Bson::Null)?);
87 }
88 let mut v = Bson::Null;
89 let m = datas.remove(0);
90 let mut doc_len = 0;
91 match &m {
92 Bson::Document(doc) => {
93 doc_len = doc.len();
94 if doc_len == 1 {
95 for (_k, _v) in doc {
96 v = _v.clone();
97 break;
98 }
99 }
100 }
101 _ => {}
102 }
103 let r = rbson::from_bson::<T>(m);
104 if r.is_err() {
105 if doc_len > 1 {
106 return Ok(r?);
107 }
108 return Ok(rbson::from_bson::<T>(v)?);
110 } else {
111 return Ok(r.unwrap());
112 }
113}
114
115#[cfg(test)]
116mod test {
117 use crate::decode::decode;
118 use crate::types::Json;
119 use rbson::bson;
120 use rbson::Bson;
121 use std::collections::{BTreeMap, HashMap, HashSet, VecDeque};
122
123 #[test]
124 fn test_decode_hashmap() {
125 let m: HashMap<String, Bson> = decode(vec![bson!(
126 {
127 "a":"1",
128 "b":2
129 }
130 )])
131 .unwrap();
132 println!("{:#?}", m);
133 }
134
135 #[test]
136 fn test_decode_btree_map() {
137 let m: BTreeMap<String, Bson> = decode(vec![bson!(
138 {
139 "a":"1",
140 "b":2
141 }
142 )])
143 .unwrap();
144 println!("{:#?}", m);
145 }
146}