quee 0.1.0

Quee is a contract-driven message queue for distributed system
Documentation
use serde::{Deserialize, Serialize};
use std::{collections::HashMap, path::PathBuf};

use crate::Error;

#[derive(Debug)]
pub enum ParseError {
    IO,
    Cycle,
    Sanity(String),
}

impl Into<Error> for ParseError {
    fn into(self) -> Error {
        Error::InternalError(format!("Parsing Error: {:?}", self))
    }
}

#[derive(Serialize, Deserialize, Debug)]
pub struct Message {
    def: String,
    default: String,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct Queue {
    pub ns: String,
    pub fork: Vec<String>,
    pub push_back: bool,
    pub message: String,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct Contract {
    pub message: HashMap<String, HashMap<String, String>>,
    pub queue: HashMap<String, Queue>,
}

pub struct ContractParser {
    file_path: PathBuf,
}

impl ContractParser {
    pub fn new(file_path: PathBuf) -> Self {
        Self { file_path }
    }

    pub fn parse(&self) -> Result<Contract, ParseError> {
        let toml_buf = std::fs::read(&self.file_path).map_err(|e| {
            eprintln!("Error while reading the toml : {}", e);
            return ParseError::IO;
        })?;
        let contract: Contract =
            toml::from_str(std::str::from_utf8(&toml_buf).unwrap()).map_err(|e| {
                eprintln!("Error while parsing \"contract.toml\" : {}", e);
                ParseError::Cycle
            })?;

        // checking if the message binded with the queue is present in the message
        // HashMap, this can be used to generating stubs and also to show the
        // details in stat command
        for k in contract.queue.keys() {
            let q = contract.queue.get(k).unwrap();
            let has_message = contract.message.get(&q.message).is_some();
            if !has_message {
                return Err(ParseError::Sanity(format!(
                    "Message: {} not found",
                    q.message
                )));
            }
        }

        Ok(contract)
    }
}