1use bigdecimal::BigDecimal;
2use oracle::sql_type::OracleType;
3use rbdc::{datetime::DateTime, Error};
4use rbs::Value;
5use std::str::FromStr;
6
7use crate::OracleData;
8
9const MISSING_STRING_VALUE: &str = "Missing string value";
10pub trait Decode {
11 fn decode(row: &OracleData) -> Result<Value, Error>;
12}
13
14impl Decode for Value {
15 fn decode(row: &OracleData) -> Result<Value, Error> {
16 if row.is_sql_null {
17 return Ok(Value::Null);
18 }
19 match row.column_type {
20 OracleType::Number(p, s) => {
21 let value = row.str.as_ref()
22 .ok_or_else(|| Error::from(MISSING_STRING_VALUE))?;
23 if p == 0 && s == -127 {
24 let dec =
26 BigDecimal::from_str(value).map_err(|e| Error::from(e.to_string()))?;
27 if dec.is_integer() {
28 let d = dec.digits();
29 if 1 <= d && d <= 9 {
30 let a = value.parse::<i32>()?;
31 return Ok(Value::I32(a));
32 } else if 10 <= d && d <= 18 {
33 let a = value.parse::<i64>()?;
34 return Ok(Value::I64(a));
35 }
36 return Ok(Value::String(dec.to_string()).into_ext("Decimal"));
37 }
38 return Ok(Value::String(dec.to_string()).into_ext("Decimal"));
39 }
40 if s > 0 {
41 let dec =
42 BigDecimal::from_str(value).map_err(|e| Error::from(e.to_string()))?;
43 return Ok(Value::String(dec.to_string()).into_ext("Decimal"));
44 } else if 1 <= p && p <= 9 {
45 let a = value.parse::<i32>()?;
46 return Ok(Value::I32(a));
47 } else if 10 <= p && p <= 18 {
48 let a = value.parse::<i64>()?;
49 return Ok(Value::I64(a));
50 }
51 let dec = BigDecimal::from_str(&value).map_err(|e| Error::from(e.to_string()))?;
52 return Ok(Value::String(dec.to_string()).into_ext("Decimal"));
53 }
54 OracleType::Int64 => {
56 let value = row.str.as_ref()
57 .ok_or_else(|| Error::from(MISSING_STRING_VALUE))?;
58 let a = value.parse::<i32>()?;
59 return Ok(Value::I32(a));
60 }
61 OracleType::Float(p) => {
62 let value = row.str.as_ref()
63 .ok_or_else(|| Error::from(MISSING_STRING_VALUE))?;
64
65 return if p >= 24 {
66 let a = value.parse::<f64>()?;
67 Ok(Value::F64(a))
68 } else {
69 let a = value.parse::<f32>()?;
70 Ok(Value::F32(a))
71 }
72 }
73 OracleType::Date => {
74 let value = row.str.as_ref()
75 .ok_or_else(|| Error::from(MISSING_STRING_VALUE))?;
76 let a = DateTime::from_str(value)?;
77 return Ok(Value::from(a));
78 }
79 OracleType::BLOB => {
80 return Ok(row.bin
81 .as_ref()
82 .map(|bin| Value::Binary((**bin).to_vec()))
83 .unwrap_or(Value::Null));
84 }
85 OracleType::Long | OracleType::CLOB | OracleType::NCLOB => {
86 let value = row
87 .str
88 .as_ref()
89 .ok_or_else(|| Error::from(MISSING_STRING_VALUE))?;
90 return Ok(Value::String((**value).to_string()));
91 }
92 _ => {
94 return row
95 .str
96 .as_ref()
97 .map(|s| Value::String((**s).to_string()))
98 .ok_or_else(|| Error::from("unimpl"))
99 },
100 };
101 }
102}