之前實作的reader有點不完整,調整一下
讀者
const MAX_BOOKS_PER_READER: usize = 5;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Reader {
pub id: String,
pub name: String,
pub borrowed_books: Vec<BorrowedBook>,
pub borrowed_history: Vec<BorrowedBook>,
}
借閱紀錄
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
pub struct BorrowedBook {
pub book_id: String,
pub borrowed_date: DateTime<Utc>,
pub due_date: DateTime<Utc>,
pub return_date: Option<DateTime<Utc>>,
}
command:
pub enum ReaderCommand {
CreateReader { name: String },
BorrowBook {
book_id: String,
borrowed_date: DateTime<Utc>,
due_date: DateTime<Utc>,
},
ReturnBook {
book_id: String,
return_date: DateTime<Utc>,
},
}
event:
pub enum ReaderEvent {
ReaderCreated { name: String, id: String },
BookBorrowed(BorrowedBook),
BookReturned(BorrowedBook),
}
實作Reader的handle:
ReaderCommand::BorrowBook { book_id, borrowed_date, due_date } => {
if self.borrowed_books.len() >= MAX_BOOKS_PER_READER {
return Err(ReaderError(format!("讀者最多只能借 {} 本書", MAX_BOOKS_PER_READER)));
}
if self.borrowed_books.iter().any(|b| b.book_id == book_id) {
return Err(ReaderError("讀者已借出同一本書".to_string()));
}
let event = ReaderEvent::BookBorrowed(
BorrowedBook {
book_id,
borrowed_date,
due_date,
return_date: None,
});
Ok(vec![event])
}
ReaderCommand::ReturnBook { book_id, return_date } => {
let borrowed_book =
self.borrowed_books
.iter()
.find(|b|
b.book_id == book_id
&& b.return_date.is_none());
if borrowed_book.is_none() {
return Err(ReaderError("讀者未借出此書".to_string()));
}
let borrowed_book = borrowed_book.unwrap();
let event = ReaderEvent::BookReturned(
BorrowedBook {
book_id: borrowed_book.book_id.clone(),
borrowed_date: borrowed_book.borrowed_date,
due_date: borrowed_book.due_date,
return_date: Some(return_date),
});
Ok(vec![event])
}
實作Reader的apply
ReaderEvent::BookBorrowed(record) => {
self.borrowed_books.push(record);
}
ReaderEvent::BookReturned(record) => {
self.borrowed_books.retain(|b|
b.book_id != record.book_id && b.borrowed_date != record.borrowed_date);
let record = BorrowedBook {
book_id: record.book_id,
borrowed_date: record.borrowed_date,
due_date: record.due_date,
return_date: Some(DateTime::from(Utc::now())),
};
self.borrowed_history.push(record);
}
實作Reader的rollabck
ReaderEvent::ReaderCreated { .. } => {
self.name = String::new();
}
ReaderEvent::BookBorrowed(record) => {
self.borrowed_books.retain(|b|
b.book_id != record.book_id && b.borrowed_date != record.borrowed_date);
}
ReaderEvent::BookReturned(record) => {
self.borrowed_history.retain(|b|
b.book_id != record.book_id && b.borrowed_date != record.borrowed_date);
self.borrowed_books.push(BorrowedBook {
book_id: record.book_id,
borrowed_date: record.borrowed_date,
due_date: record.due_date,
return_date: None,
});
}