p101_enc 0.11.0

Library to convert Olivetti P101 program to and from different encodings
Documentation
use p101_is::*;
use crate::encoding::*;

pub struct LariniDecoder {
    encoding: StandardEncoding,
    cai_mode: bool
}

impl LariniDecoder {
    pub fn new() -> Self {
        Self {
            encoding: Default::default(),
            cai_mode: false,
        }
    }

    pub fn decode(&mut self, text: &str) -> Result<Vec<Instruction>, String> {
        let mut program = Vec::new();
        let mut line_number = 1;

        for line in text.lines() {
            match line.trim() {
                "#0" => {
                    break; 
                },
                "#1" => {
                    break;
                },
                _ => {
                    match self.decode_line(line) {
                        DecodeResult::Ok(i) => {
                            self.set_mode(&i);
                            program.push(i)
                        },
                        DecodeResult::None => (),
                        DecodeResult::Err(e) => {
                            return Err(format!("{} at line {}", e, line_number))
                        }
                    }
                }
            }

            line_number += 1
        }

        if !program.is_empty() {
            Ok(program)
        } else {
            Err("No text to decode".into())
        }
    }

    fn decode_line(&self, line: &str) -> DecodeResult {
        if self.cai_mode {
            self.encoding.decode_cai(line)
        } else {
            self.encoding.decode_instr(line)
        }
    }

    fn set_mode(&mut self, i: &Instruction) {
        match i {
            Instruction::Cai(_, order, _, _) => {
                self.cai_mode = *order == CaiOrder::Low;
            },
            Instruction::CaiStart => self.cai_mode = true,
            _ => ()
        }
    }
}

impl Default for LariniDecoder {
    fn default() -> Self {
        Self::new()
    }
}