1use std::fmt::Display;
2use std::io;
3use std::num::{ParseFloatError, ParseIntError};
4use std::result::Result;
5use std::str::FromStr;
6use thiserror::Error;
7
8#[derive(Debug, Clone, Copy)]
10pub struct SdpaCoeff {
11 pub mat: usize,
12 pub block: usize,
13 pub i: usize,
14 pub j: usize,
15 pub val: f64,
16}
17
18#[derive(Error, Debug)]
19pub enum Error {
20 #[error("Error while parsing matrix coefficient: {0}")]
21 ParseError(String),
22 #[error("{0}")]
23 Io(#[from] io::Error),
24 #[error("Solver returned with code {0}")]
25 SdpNotSolved(i32),
26}
27
28use Error::*;
29
30impl From<ParseIntError> for Error {
31 fn from(e: ParseIntError) -> Self {
32 ParseError(format!("{e}"))
33 }
34}
35
36impl From<ParseFloatError> for Error {
37 fn from(e: ParseFloatError) -> Self {
38 ParseError(format!("{e}"))
39 }
40}
41
42impl FromStr for SdpaCoeff {
43 type Err = Error;
44
45 fn from_str(s: &str) -> Result<Self, Self::Err> {
46 let mut iter = s.split_whitespace();
47 let mut next = || {
48 iter.next()
49 .ok_or_else(|| ParseError("Less than 5 elements".into()))
50 };
51 let result = SdpaCoeff {
52 mat: next()?.parse()?,
53 block: next()?.parse()?,
54 i: next()?.parse()?,
55 j: next()?.parse()?,
56 val: next()?.parse()?,
57 };
58 if iter.next().is_some() {
59 return Err(ParseError("Less than 5 elements".into()));
60 };
61 Ok(result)
62 }
63}
64
65impl Display for SdpaCoeff {
66 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
67 write!(
68 f,
69 "{} {} {} {} {}",
70 self.mat, self.block, self.i, self.j, self.val
71 )
72 }
73}