| 386 | /// Prop: |
| 387 | #[staticmethod] |
| 388 | pub fn decimal(value: &Bound<'_, PyAny>) -> PyResult<Self> { |
| 389 | let bd = if value.get_type().name()?.contains("Decimal")? { |
| 390 | // decimal.Decimal — go via its str representation for full precision. |
| 391 | let s = value.str()?.to_cow()?.into_owned(); |
| 392 | BigDecimal::from_str(&s) |
| 393 | .map_err(|_| PyTypeError::new_err(format!("Could not convert {s} to Decimal")))? |
| 394 | } else if let Ok(i) = value.extract::<i64>() { |
| 395 | BigDecimal::from(i) |
| 396 | } else if let Ok(u) = value.extract::<u64>() { |
| 397 | BigDecimal::from(u) |
| 398 | } else if let Ok(f) = value.extract::<f64>() { |
| 399 | BigDecimal::try_from(f) |
| 400 | .map_err(|_| PyTypeError::new_err(format!("Could not convert {f} to Decimal")))? |
| 401 | } else if let Ok(s) = value.extract::<String>() { |
| 402 | BigDecimal::from_str(&s) |
| 403 | .map_err(|_| PyTypeError::new_err(format!("Could not convert {s} to Decimal")))? |
| 404 | } else { |
| 405 | return Err(PyTypeError::new_err(format!( |
| 406 | "Could not convert {:?} to Decimal", |
| 407 | value |
| 408 | ))); |
| 409 | }; |
| 410 | let prop = Prop::try_from_bd(bd) |
| 411 | .map_err(|_| PyTypeError::new_err(format!("Decimal too large: {value:?}")))?; |
| 412 | Ok(PyProp(prop)) |
| 413 | } |
| 414 | |
| 415 | /// Returns the `PropType` of the wrapped value. |
| 416 | /// |