use crate::error::Error; use crate::ome::{ExperimentType, MetadataOnly, MicrobeamManipulationType, XmlAnnotationValue}; use pyo3::prelude::*; use pyo3::types::PyTuple; impl From for PyErr { fn from(err: crate::error::Error) -> PyErr { color_eyre::eyre::Report::from(err).into() } } pub(crate) trait PyDisplay { fn py_str(&self) -> String; } impl PyDisplay for String { fn py_str(&self) -> String { self.clone() } } impl PyDisplay for bool { fn py_str(&self) -> String { self.to_string() } } impl PyDisplay for i32 { fn py_str(&self) -> String { self.to_string() } } impl PyDisplay for i64 { fn py_str(&self) -> String { self.to_string() } } impl PyDisplay for f32 { fn py_str(&self) -> String { self.to_string() } } impl PyDisplay for f64 { fn py_str(&self) -> String { self.to_string() } } impl PyDisplay for Option where T: PyDisplay, { fn py_str(&self) -> String { if let Some(val) = self { val.py_str() } else { "None".to_string() } } } impl PyDisplay for Vec where T: PyDisplay, { fn py_str(&self) -> String { format!( "[{}]", self.iter() .map(|x| x.py_str()) .collect::>() .join(", ") ) } } impl PyDisplay for MetadataOnly { fn py_str(&self) -> String { "MetadataOnly".into() } } impl<'a, 'py> FromPyObject<'a, 'py> for MetadataOnly { type Error = Error; fn extract(_obj: Borrowed<'a, 'py, PyAny>) -> Result { Ok(Self {}) } } impl PyDisplay for MicrobeamManipulationType { fn py_str(&self) -> String { format!( "[{}]", self.0 .iter() .map(|i| i.py_str()) .collect::>() .join(", ") ) } } impl<'a, 'py> FromPyObject<'a, 'py> for XmlAnnotationValue { type Error = Error; fn extract(_obj: Borrowed<'a, 'py, PyAny>) -> Result { Ok(Self {}) } } impl PyDisplay for XmlAnnotationValue { fn py_str(&self) -> String { "XmlAnnotationValue".to_string() } } impl PyDisplay for ExperimentType { fn py_str(&self) -> String { format!( "[{}]", self.0 .iter() .map(|i| i.py_str()) .collect::>() .join(", ") ) } } #[pymethods] impl MetadataOnly { fn __getnewargs__<'py>(&self, py: Python<'py>) -> Bound<'py, PyTuple> { PyTuple::empty(py) } fn __repr__(&self) -> String { "MetadataOnly".into() } fn __str__(&self) -> String { "MetadataOnly".into() } } #[pyfunction] fn parse_ome(text: &str) -> PyResult { Ok(crate::ome::Ome::from_xml(text)?) } #[pyfunction] fn to_xml(ome: crate::ome::Ome) -> PyResult { Ok(ome.to_xml()?) } #[pymodule] #[pyo3(name = "ome_metadata")] pub mod ome_metadata { use pyo3::prelude::*; #[pymodule_export] use super::parse_ome; #[pymodule_export] use super::to_xml; #[pymodule_export] use crate::ome::AffineTransform; #[pymodule_export] use crate::ome::Annotation; #[pymodule_export] use crate::ome::AnnotationRef; #[pymodule_export] use crate::ome::Arc; #[pymodule_export] use crate::ome::BinData; #[pymodule_export] use crate::ome::BinaryFile; #[pymodule_export] use crate::ome::BooleanAnnotation; #[pymodule_export] use crate::ome::Channel; #[pymodule_export] use crate::ome::CommentAnnotation; #[pymodule_export] use crate::ome::Dataset; #[pymodule_export] use crate::ome::Detector; #[pymodule_export] use crate::ome::DetectorSettings; #[pymodule_export] use crate::ome::Dichroic; #[pymodule_export] use crate::ome::DoubleAnnotation; #[pymodule_export] use crate::ome::Ellipse; #[pymodule_export] use crate::ome::Experiment; #[pymodule_export] use crate::ome::ExperimentType; #[pymodule_export] use crate::ome::Experimenter; #[pymodule_export] use crate::ome::ExperimenterGroup; #[pymodule_export] use crate::ome::External; #[pymodule_export] use crate::ome::Filament; #[pymodule_export] use crate::ome::FileAnnotation; #[pymodule_export] use crate::ome::Filter; #[pymodule_export] use crate::ome::FilterSet; #[pymodule_export] use crate::ome::Folder; #[pymodule_export] use crate::ome::GenericExcitationSource; #[pymodule_export] use crate::ome::Image; #[pymodule_export] use crate::ome::ImagingEnvironment; #[pymodule_export] use crate::ome::Instrument; #[pymodule_export] use crate::ome::Label; #[pymodule_export] use crate::ome::Laser; #[pymodule_export] use crate::ome::LightEmittingDiode; #[pymodule_export] use crate::ome::LightPath; #[pymodule_export] use crate::ome::LightSourceType; #[pymodule_export] use crate::ome::LightSourceSettings; #[pymodule_export] use crate::ome::Line; #[pymodule_export] use crate::ome::LongAnnotation; #[pymodule_export] use crate::ome::MapType; #[pymodule_export] use crate::ome::MapAnnotation; #[pymodule_export] use crate::ome::MapM; #[pymodule_export] use crate::ome::Mask; #[pymodule_export] use crate::ome::MetadataOnly; #[pymodule_export] use crate::ome::MicrobeamManipulation; #[pymodule_export] use crate::ome::MicrobeamManipulationType; #[pymodule_export] use crate::ome::Microscope; #[pymodule_export] use crate::ome::Ome; #[pymodule_export] use crate::ome::Objective; #[pymodule_export] use crate::ome::ObjectiveSettings; #[pymodule_export] use crate::ome::OmeBinaryOnly; #[pymodule_export] use crate::ome::Pixels; #[pymodule_export] use crate::ome::Plane; #[pymodule_export] use crate::ome::Plate; #[pymodule_export] use crate::ome::PlateAcquisition; #[pymodule_export] use crate::ome::Polygon; #[pymodule_export] use crate::ome::Polyline; #[pymodule_export] use crate::ome::Project; #[pymodule_export] use crate::ome::Roi; #[pymodule_export] use crate::ome::Reagent; #[pymodule_export] use crate::ome::Rectangle; #[pymodule_export] use crate::ome::Rights; #[pymodule_export] use crate::ome::RoiUnion; #[pymodule_export] use crate::ome::Screen; #[pymodule_export] use crate::ome::ShapeType; #[pymodule_export] use crate::ome::StageLabel; #[pymodule_export] use crate::ome::StructuredAnnotations; #[pymodule_export] use crate::ome::TiffData; #[pymodule_export] use crate::ome::TiffDataUuid; #[pymodule_export] use crate::ome::TransmittanceRange; #[pymodule_export] use crate::ome::Well; #[pymodule_export] use crate::ome::WellSample; #[pymodule_export] use crate::ome::XmlAnnotation; #[pymodule_export] use crate::ome::XmlAnnotationValue; #[pymodule_export] use crate::ome::ArcType; #[pymodule_export] use crate::ome::BinDataCompressionType; #[pymodule_export] use crate::ome::BinaryFileContent; #[pymodule_export] use crate::ome::BinningType; #[pymodule_export] use crate::ome::ChannelAcquisitionModeType; #[pymodule_export] use crate::ome::ChannelContrastMethodType; #[pymodule_export] use crate::ome::ChannelIlluminationType; #[pymodule_export] use crate::ome::DetectorType; #[pymodule_export] use crate::ome::ExperimentItemType; #[pymodule_export] use crate::ome::FilamentType; #[pymodule_export] use crate::ome::FilterType; #[pymodule_export] use crate::ome::FontFamilyType; #[pymodule_export] use crate::ome::LaserLaserMediumType; #[pymodule_export] use crate::ome::LaserPulseType; #[pymodule_export] use crate::ome::LaserType; #[pymodule_export] use crate::ome::LightSourceGroup; #[pymodule_export] use crate::ome::MarkerType; #[pymodule_export] use crate::ome::MicrobeamManipulationItemType; #[pymodule_export] use crate::ome::MicroscopeType; #[pymodule_export] use crate::ome::NamingConventionType; #[pymodule_export] use crate::ome::ObjectiveCorrectionType; #[pymodule_export] use crate::ome::ObjectiveImmersionType; #[pymodule_export] use crate::ome::ObjectiveSettingsMediumType; #[pymodule_export] use crate::ome::PixelType; #[pymodule_export] use crate::ome::PixelsDimensionOrderType; #[pymodule_export] use crate::ome::ShapeFillRuleType; #[pymodule_export] use crate::ome::ShapeFontStyleType; #[pymodule_export] use crate::ome::ShapeGroup; #[pymodule_export] use crate::ome::StructuredAnnotationsContent; #[pymodule_export] use crate::ome::UnitsElectricPotential; #[pymodule_export] use crate::ome::UnitsFrequency; #[pymodule_export] use crate::ome::UnitsLength; #[pymodule_export] use crate::ome::UnitsPower; #[pymodule_export] use crate::ome::UnitsPressure; #[pymodule_export] use crate::ome::UnitsTemperature; #[pymodule_export] use crate::ome::UnitsTime; #[pymodule_init] fn init(_: &Bound<'_, PyModule>) -> PyResult<()> { let _ = color_eyre::install(); Ok(()) } }