use std::marker::PhantomData;
use crate::{
errors::{TrajAnalysisError, TrajConvertAnalysisError, TrajConvertError},
prelude::TrajMasterRead,
system::System,
};
pub struct TrajConverter<'a, Reader, Converter>
where
Reader: ConvertableTrajRead<'a>,
Converter: FrameConvert,
{
reader: Reader,
converter: Converter,
_phantom: PhantomData<&'a Reader>,
}
pub trait FrameConvert {
type Error: std::error::Error + Send + Sync + Eq + PartialEq + 'static;
fn convert(&mut self, system: &mut System) -> Result<(), Self::Error>;
}
impl<'a, Reader, Converter> Iterator for TrajConverter<'a, Reader, Converter>
where
Reader: ConvertableTrajRead<'a>,
Converter: FrameConvert,
{
type Item = Result<&'a mut System, TrajConvertError<Converter::Error>>;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
let frame = match self.reader.next()? {
Ok(x) => x,
Err(e) => return Some(Err(TrajConvertError::ReadingError(e))),
};
match self.converter.convert(frame) {
Ok(_) => Some(Ok(frame)),
Err(e) => Some(Err(TrajConvertError::ConversionError(e))),
}
}
}
pub struct TrajAnalyzer<'a, Reader, Analyzer>
where
Reader: ConvertableTrajRead<'a>,
Analyzer: FrameAnalyze,
{
reader: Reader,
analyzer: Analyzer,
_phantom: PhantomData<&'a Reader>,
}
pub trait FrameAnalyze {
type Error: std::error::Error + Send + Sync + Eq + PartialEq + 'static;
type AnalysisResult;
fn analyze(&mut self, system: &System) -> Result<Self::AnalysisResult, Self::Error>;
}
impl<'a, Reader, Analyzer> Iterator for TrajAnalyzer<'a, Reader, Analyzer>
where
Reader: ConvertableTrajRead<'a>,
Analyzer: FrameAnalyze,
{
type Item =
Result<(&'a mut System, Analyzer::AnalysisResult), TrajAnalysisError<Analyzer::Error>>;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
let frame = match self.reader.next()? {
Ok(x) => x,
Err(e) => return Some(Err(TrajAnalysisError::ReadingError(e))),
};
match self.analyzer.analyze(frame) {
Ok(x) => Some(Ok((frame, x))),
Err(e) => Some(Err(TrajAnalysisError::AnalysisError(e))),
}
}
}
pub struct TrajConverterAnalyzer<'a, Reader, ConverterAnalyzer>
where
Reader: ConvertableTrajRead<'a>,
ConverterAnalyzer: FrameConvertAnalyze,
{
reader: Reader,
converter_analyzer: ConverterAnalyzer,
_phantom: PhantomData<&'a Reader>,
}
pub trait FrameConvertAnalyze {
type Error: std::error::Error + Send + Sync + Eq + PartialEq + 'static;
type AnalysisResult;
fn convert_analyze(&mut self, system: &mut System)
-> Result<Self::AnalysisResult, Self::Error>;
}
impl<'a, Reader, ConverterAnalyzer> Iterator
for TrajConverterAnalyzer<'a, Reader, ConverterAnalyzer>
where
Reader: ConvertableTrajRead<'a>,
ConverterAnalyzer: FrameConvertAnalyze,
{
type Item = Result<
(&'a mut System, ConverterAnalyzer::AnalysisResult),
TrajConvertAnalysisError<ConverterAnalyzer::Error>,
>;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
let frame = match self.reader.next()? {
Ok(x) => x,
Err(e) => return Some(Err(TrajConvertAnalysisError::ReadingError(e))),
};
match self.converter_analyzer.convert_analyze(frame) {
Ok(x) => Some(Ok((frame, x))),
Err(e) => Some(Err(TrajConvertAnalysisError::ConversionAnalysisError(e))),
}
}
}
pub trait ConvertableTrajRead<'a>: TrajMasterRead<'a> + Sized {
#[inline(always)]
fn convert<C>(self, converter: C) -> TrajConverter<'a, Self, C>
where
C: FrameConvert,
{
TrajConverter {
reader: self,
converter,
_phantom: PhantomData,
}
}
#[inline(always)]
fn analyze<A>(self, analyzer: A) -> TrajAnalyzer<'a, Self, A>
where
A: FrameAnalyze,
{
TrajAnalyzer {
reader: self,
analyzer,
_phantom: PhantomData,
}
}
#[inline(always)]
fn convert_and_analyze<CA>(self, converter_analyzer: CA) -> TrajConverterAnalyzer<'a, Self, CA>
where
CA: FrameConvertAnalyze,
{
TrajConverterAnalyzer {
reader: self,
converter_analyzer,
_phantom: PhantomData,
}
}
}
impl<'a, T> ConvertableTrajRead<'a> for T where T: TrajMasterRead<'a> {}