100-exercises-to-learn-rust
100-exercises-to-learn-rust copied to clipboard
exercises/07_threads/07_ack Issue: Type Mismatch in Test - Returning Option Instead of Ticket and Unwrap Usage
Issue: Type Mismatch in Test - Returning Option<Ticket> Instead of Ticket and Unwrap Usage.
feel free to check my fork for this exercise: https://github.com/RioCasanova/100-exercises-to-learn-rust
Description:
The current implementation of the server code returns an Option<Ticket> from store.get(id) and sends it using the response_sender. However, the test expects the return type of the response_receiver to be a Ticket, not an Option<Ticket>. This mismatch causes a type error during compilation. Additionally, the test is calling .unwrap() on the Ticket, which doesn't align with the expected type handling.
The test is failing with the following error:
error[E0599]: no method named `unwrap` found for struct `Ticket` in the current scope
--> exercises/07_threads/07_ack/tests/insert.rs:40:10
|
37 | let ticket: Ticket = response_receiver
| __________________________-
38 | | .recv()
| | ------ method `unwrap` is available on `Result<Ticket, RecvError>`
| 39 | | .expect("No response received!")
| 40 | | .unwrap();
| | -^^^^^^ method not found in `Ticket`
| |_________|
Problem:
- The server code is sending an
Option<Ticket>via theresponse_sender, but the test expects aTicket. This causes a type mismatch and the error related to calling.unwrap()on anOption<Ticket>. - The test is calling
.unwrap()on theTicket, which causes an error because the receiver is not returning anOption<Ticket>, it should be returningTicketdirectly.
Solution:
There are two key issues to address:
- Server code should send a
Ticketdirectly, not anOption<Ticket>. Ifstore.get(id)returnsSome(ticket), we should send thatticket. IfNoneis returned, we can handle the case by logging an error, returning a default ticket, or another method of error handling. - The test code should not call
.unwrap()on anOption<Ticket>. Since the server is expected to return aTicket, the test code can directly receive the ticket, without unwrapping it.
Updated Server Code for the Command::Get Case:
Ok(Command::Get {
id,
response_sender,
}) => {
// Retrieve the ticket by its ID
match store.get(id) {
Some(ticket) => {
// Send the ticket back
response_sender
.send(ticket)
.expect("Error sending ticket");
}
None => {
// Handle the case where the ticket doesn't exist
eprintln!("Ticket not found with ID: {:?}", id);
// Optionally send a default ticket or handle the error as needed
}
}
}
Suggestion for Fixing the Test and Server Code:
Change the Command::Get sender type to Sender<Ticket> instead of Sender<Option<Ticket>> in the Command enum:
pub enum Command {
Insert {
draft: TicketDraft,
response_sender: Sender<TicketId>,
},
Get {
id: TicketId,
response_sender: Sender<Ticket>, // Change from Option<Ticket>
},
}
In the test, you should no longer need to use .unwrap() because the server is returning a Ticket directly, not an Option<Ticket>. You can simply receive the Ticket from the receiver:
let ticket: Ticket = response_receiver
.recv()
.expect("No response received!");
assert_eq!(ticket_id, ticket.id);
assert_eq!(ticket.status, Status::ToDo);
assert_eq!(ticket.title, draft.title);
assert_eq!(ticket.description, draft.description);
Expected Behaviour:
The test should pass without errors, and the server will return a Ticket instead of an Option<Ticket>, resolving both the type mismatch and .unwrap() usage.
Steps to Reproduce:
- Run the test with the current code.
- Observe the compilation error related to
.unwrap()on theTickettype and the type mismatch when returningOption<Ticket>. - Implement the suggested solution to fix the type mismatch and re-run the test.
Expected Outcome:
The test should pass without errors, and the server code will correctly handle the received ticket, ensuring that .unwrap() is removed from the test code.