1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100

use std::error::Error;
use std::fmt;
use std::collections::HashMap;
use email_format::Email;
use internal_status::InternalStatus;
use storage::{MailstromStorage, MailstromStorageError};

#[derive(Debug)]
pub enum MemoryStorageError {
    NotFound
}
impl Error for MemoryStorageError {
    fn description(&self) -> &str {
        match *self {
            MemoryStorageError::NotFound => "Email not found"
        }
    }

    fn cause(&self) -> Option<&Error> {
        match *self {
            _ => None
        }
    }
}
impl MailstromStorageError for MemoryStorageError { }

impl fmt::Display for MemoryStorageError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Memory Storage Error: {}", self.description())
    }
}

pub struct MemoryStorage {
    emails: HashMap<String, Email>,
    statuses: HashMap<String, InternalStatus>,
}

impl MemoryStorage {
    pub fn new() -> MemoryStorage {
        MemoryStorage {
            emails: HashMap::new(),
            statuses: HashMap::new(),
        }
    }
}

impl MailstromStorage for MemoryStorage {
    type Error = MemoryStorageError;

    fn store(&mut self, email: &Email, internal_status: &InternalStatus)
             -> Result<(), MemoryStorageError>
    {
        self.emails.insert(internal_status.message_id.clone(), email.clone());
        self.statuses.insert(internal_status.message_id.clone(), internal_status.clone());
        Ok(())
    }

    fn update_status(&mut self, internal_status: &InternalStatus)
                     -> Result<(), MemoryStorageError>
    {
        self.statuses.insert(internal_status.message_id.clone(), internal_status.clone());
        Ok(())
    }

    fn retrieve(&self, message_id: &str) -> Result<(Email, InternalStatus), MemoryStorageError>
    {
        let email = match self.emails.get(message_id) {
            Some(email) => email,
            None => return Err(MemoryStorageError::NotFound),
        };
        let status = match self.statuses.get(message_id) {
            Some(status) => status,
            None => return Err(MemoryStorageError::NotFound),
        };
        Ok((email.clone(), status.clone()))
    }

    fn retrieve_status(&self, message_id: &str) -> Result<InternalStatus, MemoryStorageError>
    {
        let status = match self.statuses.get(message_id) {
            Some(status) => status,
            None => return Err(MemoryStorageError::NotFound),
        };
        Ok(status.clone())
    }

    fn retrieve_all_incomplete(&self) -> Result<Vec<InternalStatus>, Self::Error>
    {
        Ok(self.statuses.values()
           .filter_map(|is| {
               if is.attempts_remaining == 0 {
                   None
               } else {
                   Some(is.clone())
               }
           })
           .collect())
    }
}