From: Greg Burri Date: Fri, 25 Oct 2024 19:50:10 +0000 (+0200) Subject: Exercise 07-09 X-Git-Url: http://git.euphorik.ch/index.cgi?a=commitdiff_plain;h=b2f8bcee5dcb71cf0d77aa6917a59c0efd13eabb;p=rust_exercises.git Exercise 07-09 --- diff --git a/Cargo.lock b/Cargo.lock index 0dc0878..8b3bb4a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -205,6 +205,7 @@ dependencies = [ name = "bounded" version = "0.1.0" dependencies = [ + "thiserror", "ticket_fields", ] diff --git a/exercises/07_threads/09_bounded/Cargo.toml b/exercises/07_threads/09_bounded/Cargo.toml index 506d14a..9f1862c 100644 --- a/exercises/07_threads/09_bounded/Cargo.toml +++ b/exercises/07_threads/09_bounded/Cargo.toml @@ -5,3 +5,4 @@ edition = "2021" [dependencies] ticket_fields = { path = "../../../helpers/ticket_fields" } +thiserror = "1" diff --git a/exercises/07_threads/09_bounded/src/lib.rs b/exercises/07_threads/09_bounded/src/lib.rs index e661e68..4eb9d31 100644 --- a/exercises/07_threads/09_bounded/src/lib.rs +++ b/exercises/07_threads/09_bounded/src/lib.rs @@ -1,44 +1,62 @@ // TODO: Convert the implementation to use bounded channels. use crate::data::{Ticket, TicketDraft}; use crate::store::{TicketId, TicketStore}; -use std::sync::mpsc::{Receiver, Sender}; +use std::sync::mpsc::{sync_channel, Receiver, Sender, SyncSender}; pub mod data; pub mod store; #[derive(Clone)] pub struct TicketStoreClient { - sender: todo!(), + sender: SyncSender, } impl TicketStoreClient { - pub fn insert(&self, draft: TicketDraft) -> Result { - todo!() + pub fn insert(&self, draft: TicketDraft) -> Result { + let (response_sender, response_receiver) = sync_channel(1); + self.sender + .send(Command::Insert { + draft, + response_channel: response_sender, + }) + .map_err(|_| OverloadedError)?; + Ok(response_receiver.recv().unwrap()) } - pub fn get(&self, id: TicketId) -> Result, todo!()> { - todo!() + pub fn get(&self, id: TicketId) -> Result, OverloadedError> { + let (response_sender, response_receiver) = sync_channel(1); + self.sender + .send(Command::Get { + id, + response_channel: response_sender, + }) + .map_err(|_| OverloadedError)?; + Ok(response_receiver.recv().unwrap()) } } +#[derive(Debug, thiserror::Error)] +#[error("The store is overloaded")] +pub struct OverloadedError; + pub fn launch(capacity: usize) -> TicketStoreClient { - todo!(); + let (sender, receiver) = sync_channel(capacity); std::thread::spawn(move || server(receiver)); - todo!() + TicketStoreClient { sender } } enum Command { Insert { draft: TicketDraft, - response_channel: todo!(), + response_channel: SyncSender, }, Get { id: TicketId, - response_channel: todo!(), + response_channel: SyncSender>, }, } -pub fn server(receiver: Receiver) { +fn server(receiver: Receiver) { let mut store = TicketStore::new(); loop { match receiver.recv() { @@ -47,14 +65,14 @@ pub fn server(receiver: Receiver) { response_channel, }) => { let id = store.add_ticket(draft); - todo!() + response_channel.send(id).unwrap(); } Ok(Command::Get { id, response_channel, }) => { let ticket = store.get(id); - todo!() + response_channel.send(ticket.cloned()).unwrap(); } Err(_) => { // There are no more senders, so we can safely break