use std::convert::TryInto;
use std::fs::read_to_string;
use std::ops::{Add, Neg};
use std::path::Path;
use num_traits::{One, Zero};
use relp_num::NonZero;
use relp_num::Rational64;
use crate::data::linear_algebra::traits::Element;
use crate::data::linear_program::general_form::GeneralForm;
use crate::io::error::{Import, Inconsistency};
use crate::io::mps::MPS;
pub mod error;
pub mod mps;
pub fn import<F: From<Rational64> + Zero + One + Neg<Output=F> + Ord + Element + NonZero>(
file_path: &Path
) -> Result<impl TryInto<GeneralForm<F>, Error=Inconsistency>, Import>
where
for<'r> F: Add<&'r F, Output=F>,
for<'r> &'r F: Neg<Output=F>,
{
let program = read_to_string(file_path)
.map_err(Import::IO)?;
match file_path.extension() {
Some(extension) => match extension.to_str() {
Some("mps" | "SIF") => mps::parse(&program).map(DataTypes::Mps),
Some(extension_string) => Err(Import::FileExtension(format!(
"Could not recognise file extension \"{}\" of file: {:?}",
extension_string, file_path
))),
None => Err(Import::FileExtension(format!(
"Could not convert OsStr to &str, probably invalid unicode: {:?}",
extension
))),
},
None => Err(Import::FileExtension(format!(
"Could not read extension from file path: {:?}",
file_path
))),
}
}
enum DataTypes {
Mps(MPS<Rational64>),
}
impl<F> TryInto<GeneralForm<F>> for DataTypes
where
F: From<Rational64> + NonZero + Zero + One + Neg<Output=F> + Ord + Element,
for<'r> F: Add<&'r F, Output=F>,
for<'r> &'r F: Neg<Output=F>,
{
type Error = Inconsistency;
fn try_into(self) -> Result<GeneralForm<F>, Self::Error> {
match self {
DataTypes::Mps(mps) => TryInto::try_into(mps),
}
}
}