use crate::message::Card;
use std::fmt;

#[derive(Debug, PartialEq, Eq)]
pub enum StorageError {
    InvalidCard(Card),
    ReadError(String),
    WriteError(String)
}

impl fmt::Display for StorageError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { 
        let msg = match self {
            StorageError::InvalidCard(card) => format!("Invalid card {:?}", card),
            StorageError::ReadError(error) => format!("Cannot read card: {}", error),
            StorageError::WriteError(error) => format!("Cannot write card: {}", error)
        };

        write!(f, "{}", msg)
    }
}

pub trait StorageProvider {
    /// A card has been inserted in the reader. The provider
    /// have to remember the card for later write.
    fn using(&mut self, card: Card) -> Result<(), StorageError>;

    /// The provider returns card content or fail with an error.
    /// This method is stateless.
    fn read(&self) -> Result<String, StorageError>;

    /// The provider stores the new_text on the card
    /// or fail with an error.
    fn write(&mut self, new_text: &str) -> Result<(), StorageError>;
}
