polars_core/chunked_array/ops/
decimal.rs1use crate::chunked_array::cast::CastOptions;
2use crate::prelude::*;
3
4impl StringChunked {
5 pub fn to_decimal(&self, infer_length: usize) -> PolarsResult<Series> {
13 let mut scale = 0;
14 let mut iter = self.into_iter();
15 let mut valid_count = 0;
16 while let Some(Some(v)) = iter.next() {
17 let scale_value = arrow::compute::decimal::infer_scale(v.as_bytes());
18 scale = std::cmp::max(scale, scale_value);
19 valid_count += 1;
20 if valid_count == infer_length {
21 break;
22 }
23 }
24
25 self.cast_with_options(
26 &DataType::Decimal(None, Some(scale as usize)),
27 CastOptions::NonStrict,
28 )
29 }
30}
31
32#[cfg(test)]
33mod test {
34 #[test]
35 fn test_inferred_length() {
36 use super::*;
37 let vals = [
38 "1.0",
39 "invalid",
40 "225.0",
41 "3.00045",
42 "-4.0",
43 "5.104",
44 "5.25251525353",
45 ];
46 let s = StringChunked::from_slice(PlSmallStr::from_str("test"), &vals);
47 let s = s.to_decimal(6).unwrap();
48 assert_eq!(s.dtype(), &DataType::Decimal(None, Some(5)));
49 assert_eq!(s.len(), 7);
50 assert_eq!(s.get(0).unwrap(), AnyValue::Decimal(100000, 5));
51 assert_eq!(s.get(1).unwrap(), AnyValue::Null);
52 assert_eq!(s.get(3).unwrap(), AnyValue::Decimal(300045, 5));
53 assert_eq!(s.get(4).unwrap(), AnyValue::Decimal(-400000, 5));
54 assert_eq!(s.get(6).unwrap(), AnyValue::Decimal(525251, 5));
55 }
56}