use super::{Pressure, Quantity, SIUnit, Temperature}; use crate::state::TPSpec; use crate::{EosError, EosResult}; use ndarray::{Array1, Array2, Array3, Array4}; use quantity::python::{PySIArray1, PySIArray2, PySIArray3, PySIArray4, PySINumber}; use quantity::si; use quantity::Quantity as PyQuantity; use std::convert::TryFrom; use std::marker::PhantomData; use std::ops::{Div, Mul}; use typenum::Integer; impl< Inner, T: Integer, L: Integer, M: Integer, I: Integer, THETA: Integer, N: Integer, J: Integer, > TryFrom> for Quantity> where for<'a> &'a Inner: Div, PyQuantity: std::fmt::Display, { type Error = EosError; fn try_from(quantity: PyQuantity) -> EosResult { let (value, unit_from) = quantity.into_raw_parts(); let unit_into = [L::I8, M::I8, T::I8, I::I8, N::I8, THETA::I8, J::I8]; if unit_into == unit_from { Ok(Quantity(value, PhantomData)) } else { Err(EosError::WrongUnits( si::SIUnit::from_raw_parts(unit_into).to_string(), PyQuantity::from_raw_parts(value, unit_from).to_string(), )) } } } impl TryFrom for Quantity> { type Error = >>::Error; fn try_from(value: PySINumber) -> Result { Self::try_from(PyQuantity::from(value)) } } impl TryFrom for Quantity, SIUnit> { type Error = , si::SIUnit>>>::Error; fn try_from(value: PySIArray1) -> Result { Self::try_from(PyQuantity::from(value)) } } impl TryFrom for Quantity, SIUnit> { type Error = , si::SIUnit>>>::Error; fn try_from(value: PySIArray2) -> Result { Self::try_from(PyQuantity::from(value)) } } impl TryFrom for Quantity, SIUnit> { type Error = , si::SIUnit>>>::Error; fn try_from(value: PySIArray3) -> Result { Self::try_from(PyQuantity::from(value)) } } impl TryFrom for Quantity, SIUnit> { type Error = , si::SIUnit>>>::Error; fn try_from(value: PySIArray4) -> Result { Self::try_from(PyQuantity::from(value)) } } impl< Inner, T: Integer, L: Integer, M: Integer, I: Integer, THETA: Integer, N: Integer, J: Integer, > From>> for PyQuantity where Inner: Mul>, { fn from(quantity: Quantity>) -> Self { Self::from_raw_parts( quantity.0, [L::I8, M::I8, T::I8, I::I8, N::I8, THETA::I8, J::I8], ) } } impl From>> for PySINumber { fn from(quantity: Quantity>) -> Self { Self::from(PyQuantity::from(quantity)) } } impl From, SIUnit>> for PySIArray1 { fn from(quantity: Quantity, SIUnit>) -> Self { Self::from(PyQuantity::from(quantity)) } } impl From, SIUnit>> for PySIArray2 { fn from(quantity: Quantity, SIUnit>) -> Self { Self::from(PyQuantity::from(quantity)) } } impl From, SIUnit>> for PySIArray3 { fn from(quantity: Quantity, SIUnit>) -> Self { Self::from(PyQuantity::from(quantity)) } } impl From, SIUnit>> for PySIArray4 { fn from(quantity: Quantity, SIUnit>) -> Self { Self::from(PyQuantity::from(quantity)) } } impl TryFrom for TPSpec { type Error = EosError; fn try_from(quantity: PySINumber) -> EosResult { let quantity = PyQuantity::from(quantity); if let Ok(t) = Temperature::::try_from(quantity) { return Ok(TPSpec::Temperature(t)); } if let Ok(p) = Pressure::::try_from(quantity) { return Ok(TPSpec::Pressure(p)); } Err(EosError::WrongUnits( "temperature or pressure".into(), quantity.to_string(), )) } }