| 436 | impl<'py> FromPyObject<'_, 'py> for Prop { |
| 437 | type Error = PyErr; |
| 438 | fn extract(ob: Borrowed<'_, 'py, PyAny>) -> PyResult<Self> { |
| 439 | if let Ok(pyref) = ob.extract::<PyRef<PyProp>>() { |
| 440 | return Ok(pyref.0.clone()); |
| 441 | } |
| 442 | |
| 443 | if ob.is_instance_of::<PyBool>() { |
| 444 | return Ok(Prop::Bool(ob.extract()?)); |
| 445 | } |
| 446 | |
| 447 | if let Ok(v) = ob.extract() { |
| 448 | return Ok(Prop::I64(v)); |
| 449 | } |
| 450 | |
| 451 | if let Ok(v) = ob.extract() { |
| 452 | return Ok(Prop::U64(v)); |
| 453 | } |
| 454 | |
| 455 | if ob.get_type().name()?.contains("Decimal")? { |
| 456 | // this sits before f64, otherwise it will be picked up as f64 |
| 457 | let py_str = &ob.str()?; |
| 458 | let rs_str = &py_str.to_cow()?; |
| 459 | |
| 460 | return BigDecimal::from_str(rs_str) |
| 461 | .map_err(|_| { |
| 462 | PyTypeError::new_err(format!("Could not convert {} to Decimal", rs_str)) |
| 463 | }) |
| 464 | .and_then(|bd| { |
| 465 | Prop::try_from_bd(bd) |
| 466 | .map_err(|_| PyTypeError::new_err(format!("Decimal too large {}", rs_str))) |
| 467 | }); |
| 468 | } |
| 469 | |
| 470 | if let Ok(v) = ob.extract() { |
| 471 | return Ok(Prop::F64(v)); |
| 472 | } |
| 473 | |
| 474 | if let Ok(d) = ob.extract() { |
| 475 | return Ok(Prop::NDTime(d)); |
| 476 | } |
| 477 | |
| 478 | if let Ok(d) = ob.extract() { |
| 479 | return Ok(Prop::DTime(d)); |
| 480 | } |
| 481 | |
| 482 | if let Ok(s) = ob.extract::<String>() { |
| 483 | return Ok(Prop::Str(s.into())); |
| 484 | } |
| 485 | if let Ok(arrow) = ob.extract::<PyArray>() { |
| 486 | let (arr, _) = arrow.into_inner(); |
| 487 | return Ok(Prop::List(PropArray::Array(arr))); |
| 488 | } |
| 489 | if let Ok(list) = ob.extract::<Vec<Prop>>() { |
| 490 | return Ok(Prop::List(PropArray::Vec(list.into()))); |
| 491 | } |
| 492 | |
| 493 | if let Ok(map) = ob.extract() { |
| 494 | return Ok(Prop::Map(Arc::new(map))); |
| 495 | } |