fn parse<'a, F: Parse, CR: ColumnRetriever<'a>>(
    program_string: &'a str,
) -> Result<MPS<F>, ImportError> {
    // Go through the file line by line
    let mut lines = into_lines(program_string);

    // Extract the program name
    let name = parse_program_name::<CR>(lines.next())
        .map_err(|e| e.wrap("Error while parsing reading the program name."))?;

    // Go through the file, line by line, section by section. We never look back.
    // The below call removes the line that indicates the start of the ROWS section.
    let objective = parse_objsense_section(&mut lines)?;

    let (cost_row_name, rows) = parse_row_section::<CR, _>(&mut lines)?;
    let (cost_row_name, rows) = check_row_section_consistency(cost_row_name, rows)?;
    let row_index = build_row_index(&rows, &cost_row_name)?;

    // All sections after this one are optional, so the next section is read by the previous method.

    let (columns, cost_values, next_section) =
        parse_column_section::<_, CR, _>(&mut lines, &cost_row_name, &row_index)?;
    let column_index = build_column_index(&columns);

    let (rhss, next_section) = if next_section == Section::Rhs {
        parse_optional_section::<_, CR, _, _, 2>(&mut lines, [Section::Ranges, Section::Bounds], &row_index)?
    } else { (Vec::with_capacity(0), next_section) };

    let (ranges, next_section) = if next_section == Section::Ranges {
        parse_optional_section::<_, CR, _, _, 1>(&mut lines, [Section::Bounds], &row_index)?
    } else { (Vec::with_capacity(0), next_section) };
    check_ranges_consistency(&ranges)?;

    let bounds = if next_section == Section::Bounds {
        parse_bounds_section::<_, CR, _>(&mut lines, &column_index)?
    } else { Vec::with_capacity(0) };

    if lines.next().is_some() {
        return Err(ParseError::new("File parsed successfully, but it has nonempty lines a\
        t the end").into());
    }

    Ok(MPS {
        name,
        objective,
        cost_row_name,
        cost_values,
        rows,
        columns,
        rhss,
        ranges,
        bounds,
    })
}
/// Parse an MPS file in either the fixed or free format.
///
/// This method is written to be fast and is not "defensive" at all. E.g. when there is an extra
/// value on a line, this value will just be ignored.
///
/// # Arguments
///
/// * `program_string`: String holding the entire program.
///
/// # Errors
///
/// Parse Errors if the file format is found out to be wrong, Inconsistency errors if e.g. a row is
/// mentioned that wasn't declared in advance.
Parse an MPS file in either the fixed or free format.
This method is written to be fast and is not "defensive" at all.
Parse an MPS file in either the fixed or free format . This method is written to be fast and is not " defensive " at all .
fn parse<'a, F: Parse, CR: ColumnRetriever<'a>>(
    program_string: &'a str,
) -> Result<MPS<F>, ImportError> {
    // Go through the file line by line
    let mut lines = into_lines(program_string);
    // Extract the program name
    let name = parse_program_name::<CR>(lines.next())
        .map_err(|e| e.wrap("Error while parsing reading the program name."))?;
    // Go through the file, line by line, section by section. We never look back.
    // The below call removes the line that indicates the start of the ROWS section.
    let objective = parse_objsense_section(&mut lines)?;
    let (cost_row_name, rows) = parse_row_section::<CR, _>(&mut lines)?;
    let (cost_row_name, rows) = check_row_section_consistency(cost_row_name, rows)?;
    let row_index = build_row_index(&rows, &cost_row_name)?;
    // All sections after this one are optional, so the next section is read by the previous method.
    let (columns, cost_values, next_section) =
        parse_column_section::<_, CR, _>(&mut lines, &cost_row_name, &row_index)?;
    let column_index = build_column_index(&columns);
    let (rhss, next_section) = if next_section == Section::Rhs {
        parse_optional_section::<_, CR, _, _, 2>(&mut lines, [Section::Ranges, Section::Bounds], &row_index)?
    } else { (Vec::with_capacity(0), next_section) };
    let (ranges, next_section) = if next_section == Section::Ranges {
        parse_optional_section::<_, CR, _, _, 1>(&mut lines, [Section::Bounds], &row_index)?
    } else { (Vec::with_capacity(0), next_section) };
    check_ranges_consistency(&ranges)?;
    let bounds = if next_section == Section::Bounds {
        parse_bounds_section::<_, CR, _>(&mut lines, &column_index)?
    } else { Vec::with_capacity(0) };
    if lines.next().is_some() {
        return Err(ParseError::new("File parsed successfully, but it has nonempty lines a\
        t the end").into());
    }
    Ok(MPS {
        name,
        objective,
        cost_row_name,
        cost_values,
        rows,
        columns,
        rhss,
        ranges,
        bounds,
    })
}
fn parse < ' a , F : Parse , CR : ColumnRetriever < ' a > > ( program_string : & ' a str , ) -> Result < MPS < F > , ImportError > { // Go through the file line by line let mut lines = into_lines ( program_string ) ; // Extract the program name let name = parse_program_name :: < CR > ( lines . next ( ) ) . map_err ( | e | e . wrap ( " " ) ) ? ; // Go through the file, line by line, section by section. We never look back. // The below call removes the line that indicates the start of the ROWS section. let objective = parse_objsense_section ( & mut lines ) ? ; let ( cost_row_name , rows ) = parse_row_section :: < CR , _ > ( & mut lines ) ? ; let ( cost_row_name , rows ) = check_row_section_consistency ( cost_row_name , rows ) ? ; let row_index = build_row_index ( & rows , & cost_row_name ) ? ; // All sections after this one are optional, so the next section is read by the previous method. let ( columns , cost_values , next_section ) = parse_column_section :: < _ , CR , _ > ( & mut lines , & cost_row_name , & row_index ) ? ; let column_index = build_column_index ( & columns ) ; let ( rhss , next_section ) = if next_section == Section :: Rhs { parse_optional_section :: < _ , CR , _ , _ , 2 > ( & mut lines , [ Section :: Ranges , Section :: Bounds ] , & row_index ) ? } else { ( Vec :: with_capacity ( 0 ) , next_section ) } ; let ( ranges , next_section ) = if next_section == Section :: Ranges { parse_optional_section :: < _ , CR , _ , _ , 1 > ( & mut lines , [ Section :: Bounds ] , & row_index ) ? } else { ( Vec :: with_capacity ( 0 ) , next_section ) } ; check_ranges_consistency ( & ranges ) ? ; let bounds = if next_section == Section :: Bounds { parse_bounds_section :: < _ , CR , _ > ( & mut lines , & column_index ) ? } else { Vec :: with_capacity ( 0 ) } ; if lines . next ( ) . is_some ( ) { return Err ( ParseError :: new ( " \
 " ) . into ( ) ) ; } Ok ( MPS { name , objective , cost_row_name , cost_values , rows , columns , rhss , ranges , bounds , } ) }
Parse an MPS file in either the fixed or free format.
Parse an MPS file in either the fixed or free format .
program_string
&'a str
program_string
&'a str
errors
Parse Errors if the file format is found out to be wrong, Inconsistency errors if e.g. a row is
mentioned that wasn't declared in advance.
Parse Errors if the file format is found out to be wrong Inconsistency errors if e . g . a row is mentioned that wasn ' t declared in advance .