From 8413518a84b7fed4861d1527d0bd80f781ae43d6 Mon Sep 17 00:00:00 2001 From: Phani Pavan K Date: Mon, 17 Mar 2025 06:39:58 +0530 Subject: [PATCH] completed most of 05 ticket v2 --- Cargo.lock | 6 +++- exercises/05_ticket_v2/01_enum/src/lib.rs | 13 +++++--- exercises/05_ticket_v2/02_match/src/lib.rs | 8 ++++- .../03_variants_with_data/src/lib.rs | 8 +++-- exercises/05_ticket_v2/04_if_let/src/lib.rs | 13 +++++++- .../05_ticket_v2/05_nullability/src/lib.rs | 5 ++- .../05_ticket_v2/06_fallibility/src/lib.rs | 14 ++++---- exercises/05_ticket_v2/07_unwrap/src/lib.rs | 20 ++++++++++- .../05_ticket_v2/08_error_enums/src/lib.rs | 33 +++++++++++++++---- .../05_ticket_v2/09_error_trait/src/lib.rs | 26 ++++++++++++++- exercises/05_ticket_v2/10_packages/src/lib.rs | 1 + .../05_ticket_v2/11_dependencies/Cargo.toml | 3 ++ .../05_ticket_v2/12_thiserror/Cargo.toml | 2 +- .../05_ticket_v2/12_thiserror/src/lib.rs | 7 ++++ 14 files changed, 132 insertions(+), 27 deletions(-) create mode 100644 exercises/05_ticket_v2/10_packages/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index d560369..d8e2ccf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" @@ -443,6 +443,9 @@ dependencies = [ [[package]] name = "deps" version = "0.1.0" +dependencies = [ + "anyhow", +] [[package]] name = "deref" @@ -2175,6 +2178,7 @@ name = "thiserror_" version = "0.1.0" dependencies = [ "common", + "thiserror", ] [[package]] diff --git a/exercises/05_ticket_v2/01_enum/src/lib.rs b/exercises/05_ticket_v2/01_enum/src/lib.rs index a3d9592..487873f 100644 --- a/exercises/05_ticket_v2/01_enum/src/lib.rs +++ b/exercises/05_ticket_v2/01_enum/src/lib.rs @@ -7,15 +7,18 @@ struct Ticket { title: String, description: String, - status: String, + status: Status, } +#[derive(Debug, PartialEq, Clone, Copy)] enum Status { - // TODO: add the missing variants + ToDo, + InProgress, + Done, } impl Ticket { - pub fn new(title: String, description: String, status: String) -> Ticket { + pub fn new(title: String, description: String, status: Status) -> Ticket { if title.is_empty() { panic!("Title cannot be empty"); } @@ -28,7 +31,7 @@ impl Ticket { if description.len() > 500 { panic!("Description cannot be longer than 500 bytes"); } - if status != "To-Do" && status != "In Progress" && status != "Done" { + if status != Status::ToDo && status != Status::InProgress && status != Status::Done { panic!("Only `To-Do`, `In Progress`, and `Done` statuses are allowed"); } @@ -47,7 +50,7 @@ impl Ticket { &self.description } - pub fn status(&self) -> &String { + pub fn status(&self) -> &Status { &self.status } } diff --git a/exercises/05_ticket_v2/02_match/src/lib.rs b/exercises/05_ticket_v2/02_match/src/lib.rs index d30c569..07e33fd 100644 --- a/exercises/05_ticket_v2/02_match/src/lib.rs +++ b/exercises/05_ticket_v2/02_match/src/lib.rs @@ -9,7 +9,13 @@ enum Shape { impl Shape { // TODO: Implement the `n_sides` method using a `match`. pub fn n_sides(&self) -> u8 { - todo!() + match self { + Self::Circle => 0, + Self::Pentagon => 5, + Self::Rectangle => 4, + Self::Square => 4, + Self::Triangle => 3, + } } } diff --git a/exercises/05_ticket_v2/03_variants_with_data/src/lib.rs b/exercises/05_ticket_v2/03_variants_with_data/src/lib.rs index 03faf0c..2edb294 100644 --- a/exercises/05_ticket_v2/03_variants_with_data/src/lib.rs +++ b/exercises/05_ticket_v2/03_variants_with_data/src/lib.rs @@ -9,7 +9,7 @@ struct Ticket { status: Status, } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Clone)] enum Status { ToDo, InProgress { assigned_to: String }, @@ -38,7 +38,11 @@ impl Ticket { } } pub fn assigned_to(&self) -> &str { - todo!() + match &self.status { + Status::InProgress { assigned_to } => assigned_to, + _ => panic!("Only `In-Progress` tickets can be assigned to someone"), + } + // let Status::InProgress { assigned_to } = self.status; } } diff --git a/exercises/05_ticket_v2/04_if_let/src/lib.rs b/exercises/05_ticket_v2/04_if_let/src/lib.rs index 0884fb5..eb223f5 100644 --- a/exercises/05_ticket_v2/04_if_let/src/lib.rs +++ b/exercises/05_ticket_v2/04_if_let/src/lib.rs @@ -7,8 +7,19 @@ enum Shape { impl Shape { // TODO: Implement the `radius` method using // either an `if let` or a `let/else`. + // pub fn radius(&self) -> f64 { + // if let Shape::Circle { radius } = self { + // return radius.clone(); + // } else { + // panic!(""); + // } + // } + pub fn radius(&self) -> f64 { - todo!() + let Shape::Circle { radius } = self else { + panic!(""); + }; + radius.clone() } } diff --git a/exercises/05_ticket_v2/05_nullability/src/lib.rs b/exercises/05_ticket_v2/05_nullability/src/lib.rs index f4e5cb2..e981e2b 100644 --- a/exercises/05_ticket_v2/05_nullability/src/lib.rs +++ b/exercises/05_ticket_v2/05_nullability/src/lib.rs @@ -36,7 +36,10 @@ impl Ticket { } } pub fn assigned_to(&self) -> Option<&String> { - todo!() + let Status::InProgress { assigned_to } = &self.status else { + return None; + }; + Some(assigned_to) } } diff --git a/exercises/05_ticket_v2/06_fallibility/src/lib.rs b/exercises/05_ticket_v2/06_fallibility/src/lib.rs index 3144bee..de9bc30 100644 --- a/exercises/05_ticket_v2/06_fallibility/src/lib.rs +++ b/exercises/05_ticket_v2/06_fallibility/src/lib.rs @@ -16,25 +16,25 @@ enum Status { } impl Ticket { - pub fn new(title: String, description: String, status: Status) -> Ticket { + pub fn new(title: String, description: String, status: Status) -> Result { if title.is_empty() { - panic!("Title cannot be empty"); + return Err("Title cannot be empty".to_string()); } if title.len() > 50 { - panic!("Title cannot be longer than 50 bytes"); + return Err("Title cannot be longer than 50 bytes".to_string()); } if description.is_empty() { - panic!("Description cannot be empty"); + return Err("Description cannot be empty".to_string()); } if description.len() > 500 { - panic!("Description cannot be longer than 500 bytes"); + return Err("Description cannot be longer than 500 bytes".to_string()); } - Ticket { + Ok(Ticket { title, description, status, - } + }) } } diff --git a/exercises/05_ticket_v2/07_unwrap/src/lib.rs b/exercises/05_ticket_v2/07_unwrap/src/lib.rs index 4b6419b..155ee53 100644 --- a/exercises/05_ticket_v2/07_unwrap/src/lib.rs +++ b/exercises/05_ticket_v2/07_unwrap/src/lib.rs @@ -2,7 +2,25 @@ // When the description is invalid, instead, it should use a default description: // "Description not provided". fn easy_ticket(title: String, description: String, status: Status) -> Ticket { - todo!() + let tick = Ticket::new(title.clone(), description.clone(), status.clone()); + match tick { + Ok(res) => return res, + Err(err) => { + match err.as_str() { + "Description cannot be empty" | "Description cannot be longer than 500 bytes" => { + return Ticket { + title: title.clone(), + description: "Description not provided".to_string(), + status: status.clone(), + }; + } + + _ => { + panic!("{err}"); + } + }; + } + } } #[derive(Debug, PartialEq, Clone)] diff --git a/exercises/05_ticket_v2/08_error_enums/src/lib.rs b/exercises/05_ticket_v2/08_error_enums/src/lib.rs index c74fcc9..1537ca4 100644 --- a/exercises/05_ticket_v2/08_error_enums/src/lib.rs +++ b/exercises/05_ticket_v2/08_error_enums/src/lib.rs @@ -1,14 +1,27 @@ // TODO: Use two variants, one for a title error and one for a description error. // Each variant should contain a string with the explanation of what went wrong exactly. // You'll have to update the implementation of `Ticket::new` as well. -enum TicketNewError {} +enum TicketNewError { + TitleError { desc: String }, + DescError { desc: String }, +} // TODO: `easy_ticket` should panic when the title is invalid, using the error message // stored inside the relevant variant of the `TicketNewError` enum. // When the description is invalid, instead, it should use a default description: // "Description not provided". fn easy_ticket(title: String, description: String, status: Status) -> Ticket { - todo!() + match Ticket::new(title.clone(), description, status.clone()) { + Ok(proper) => proper, + Err(TicketNewError::DescError { desc }) => Ticket { + title: title.clone(), + description: "Description not provided".to_string(), + status: status.clone(), + }, + Err(TicketNewError::TitleError { desc }) => { + panic!("{desc}"); + } + } } #[derive(Debug, PartialEq)] @@ -32,16 +45,24 @@ impl Ticket { status: Status, ) -> Result { if title.is_empty() { - return Err("Title cannot be empty".to_string()); + return Err(TicketNewError::TitleError { + desc: "Title cannot be empty".to_string(), + }); } if title.len() > 50 { - return Err("Title cannot be longer than 50 bytes".to_string()); + return Err(TicketNewError::TitleError { + desc: "Title cannot be longer than 50 bytes".to_string(), + }); } if description.is_empty() { - return Err("Description cannot be empty".to_string()); + return Err(TicketNewError::DescError { + desc: "Description cannot be empty".to_string(), + }); } if description.len() > 500 { - return Err("Description cannot be longer than 500 bytes".to_string()); + return Err(TicketNewError::DescError { + desc: "Description cannot be longer than 500 bytes".to_string(), + }); } Ok(Ticket { diff --git a/exercises/05_ticket_v2/09_error_trait/src/lib.rs b/exercises/05_ticket_v2/09_error_trait/src/lib.rs index 68b5769..016d176 100644 --- a/exercises/05_ticket_v2/09_error_trait/src/lib.rs +++ b/exercises/05_ticket_v2/09_error_trait/src/lib.rs @@ -3,17 +3,41 @@ // The docs for the `std::fmt` module are a good place to start and look for examples: // https://doc.rust-lang.org/std/fmt/index.html#write +use std::error::Error; +use std::fmt::{Display, Formatter}; + +#[derive(Debug)] enum TicketNewError { TitleError(String), DescriptionError(String), } +impl Display for TicketNewError { + fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> { + match self { + TicketNewError::TitleError(msg) => write!(f, "{msg}"), + TicketNewError::DescriptionError(msg) => write!(f, "{msg}"), + } + // write!(f, "") + } +} + +impl Error for TicketNewError {} + // TODO: `easy_ticket` should panic when the title is invalid, using the error message // stored inside the relevant variant of the `TicketNewError` enum. // When the description is invalid, instead, it should use a default description: // "Description not provided". fn easy_ticket(title: String, description: String, status: Status) -> Ticket { - todo!() + match Ticket::new(title.clone(), description, status.clone()) { + Ok(ticket) => ticket, + Err(err) => match err { + TicketNewError::TitleError(_) => panic!("{err}"), + TicketNewError::DescriptionError(_) => { + Ticket::new(title, "Description not provided".to_string(), status).unwrap() + } + }, + } } #[derive(Debug, PartialEq, Clone)] diff --git a/exercises/05_ticket_v2/10_packages/src/lib.rs b/exercises/05_ticket_v2/10_packages/src/lib.rs new file mode 100644 index 0000000..5c464a9 --- /dev/null +++ b/exercises/05_ticket_v2/10_packages/src/lib.rs @@ -0,0 +1 @@ +pub fn hello_world() {} diff --git a/exercises/05_ticket_v2/11_dependencies/Cargo.toml b/exercises/05_ticket_v2/11_dependencies/Cargo.toml index c18abf9..3f52dde 100644 --- a/exercises/05_ticket_v2/11_dependencies/Cargo.toml +++ b/exercises/05_ticket_v2/11_dependencies/Cargo.toml @@ -2,3 +2,6 @@ name = "deps" version = "0.1.0" edition = "2021" + +[dependencies] +anyhow = "*" diff --git a/exercises/05_ticket_v2/12_thiserror/Cargo.toml b/exercises/05_ticket_v2/12_thiserror/Cargo.toml index fb9c7d5..c5a2523 100644 --- a/exercises/05_ticket_v2/12_thiserror/Cargo.toml +++ b/exercises/05_ticket_v2/12_thiserror/Cargo.toml @@ -4,6 +4,6 @@ version = "0.1.0" edition = "2021" [dependencies] - +thiserror = "*" [dev-dependencies] common = { path = "../../../helpers/common" } diff --git a/exercises/05_ticket_v2/12_thiserror/src/lib.rs b/exercises/05_ticket_v2/12_thiserror/src/lib.rs index 9289143..7376258 100644 --- a/exercises/05_ticket_v2/12_thiserror/src/lib.rs +++ b/exercises/05_ticket_v2/12_thiserror/src/lib.rs @@ -3,10 +3,17 @@ // a `String` field into each variant. // You'll also have to add `thiserror` as a dependency in the `Cargo.toml` file. +use thiserror::Error; + +#[derive(thiserror::Error, Debug)] enum TicketNewError { + #[error("Title cannot be empty")] TitleCannotBeEmpty, + #[error("Title cannot be longer than 50 bytes")] TitleTooLong, + #[error("Description cannot be empty")] DescriptionCannotBeEmpty, + #[error("Description cannot be longer than 500 bytes")] DescriptionTooLong, }