completed most of 05 ticket v2

This commit is contained in:
2025-03-17 06:39:58 +05:30
parent 8d1342c831
commit 8413518a84
14 changed files with 132 additions and 27 deletions

6
Cargo.lock generated
View File

@@ -1,6 +1,6 @@
# This file is automatically @generated by Cargo. # This file is automatically @generated by Cargo.
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 4
[[package]] [[package]]
name = "addr2line" name = "addr2line"
@@ -443,6 +443,9 @@ dependencies = [
[[package]] [[package]]
name = "deps" name = "deps"
version = "0.1.0" version = "0.1.0"
dependencies = [
"anyhow",
]
[[package]] [[package]]
name = "deref" name = "deref"
@@ -2175,6 +2178,7 @@ name = "thiserror_"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"common", "common",
"thiserror",
] ]
[[package]] [[package]]

View File

@@ -7,15 +7,18 @@
struct Ticket { struct Ticket {
title: String, title: String,
description: String, description: String,
status: String, status: Status,
} }
#[derive(Debug, PartialEq, Clone, Copy)]
enum Status { enum Status {
// TODO: add the missing variants ToDo,
InProgress,
Done,
} }
impl Ticket { 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() { if title.is_empty() {
panic!("Title cannot be empty"); panic!("Title cannot be empty");
} }
@@ -28,7 +31,7 @@ impl Ticket {
if description.len() > 500 { if description.len() > 500 {
panic!("Description cannot be longer than 500 bytes"); 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"); panic!("Only `To-Do`, `In Progress`, and `Done` statuses are allowed");
} }
@@ -47,7 +50,7 @@ impl Ticket {
&self.description &self.description
} }
pub fn status(&self) -> &String { pub fn status(&self) -> &Status {
&self.status &self.status
} }
} }

View File

@@ -9,7 +9,13 @@ enum Shape {
impl Shape { impl Shape {
// TODO: Implement the `n_sides` method using a `match`. // TODO: Implement the `n_sides` method using a `match`.
pub fn n_sides(&self) -> u8 { pub fn n_sides(&self) -> u8 {
todo!() match self {
Self::Circle => 0,
Self::Pentagon => 5,
Self::Rectangle => 4,
Self::Square => 4,
Self::Triangle => 3,
}
} }
} }

View File

@@ -9,7 +9,7 @@ struct Ticket {
status: Status, status: Status,
} }
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq, Clone)]
enum Status { enum Status {
ToDo, ToDo,
InProgress { assigned_to: String }, InProgress { assigned_to: String },
@@ -38,7 +38,11 @@ impl Ticket {
} }
} }
pub fn assigned_to(&self) -> &str { 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;
} }
} }

View File

@@ -7,8 +7,19 @@ enum Shape {
impl Shape { impl Shape {
// TODO: Implement the `radius` method using // TODO: Implement the `radius` method using
// either an `if let` or a `let/else`. // 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 { pub fn radius(&self) -> f64 {
todo!() let Shape::Circle { radius } = self else {
panic!("");
};
radius.clone()
} }
} }

View File

@@ -36,7 +36,10 @@ impl Ticket {
} }
} }
pub fn assigned_to(&self) -> Option<&String> { pub fn assigned_to(&self) -> Option<&String> {
todo!() let Status::InProgress { assigned_to } = &self.status else {
return None;
};
Some(assigned_to)
} }
} }

View File

@@ -16,25 +16,25 @@ enum Status {
} }
impl Ticket { impl Ticket {
pub fn new(title: String, description: String, status: Status) -> Ticket { pub fn new(title: String, description: String, status: Status) -> Result<Ticket, String> {
if title.is_empty() { if title.is_empty() {
panic!("Title cannot be empty"); return Err("Title cannot be empty".to_string());
} }
if title.len() > 50 { 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() { if description.is_empty() {
panic!("Description cannot be empty"); return Err("Description cannot be empty".to_string());
} }
if description.len() > 500 { 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, title,
description, description,
status, status,
} })
} }
} }

View File

@@ -2,7 +2,25 @@
// When the description is invalid, instead, it should use a default description: // When the description is invalid, instead, it should use a default description:
// "Description not provided". // "Description not provided".
fn easy_ticket(title: String, description: String, status: Status) -> Ticket { 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)] #[derive(Debug, PartialEq, Clone)]

View File

@@ -1,14 +1,27 @@
// TODO: Use two variants, one for a title error and one for a description error. // 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. // 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. // 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 // TODO: `easy_ticket` should panic when the title is invalid, using the error message
// stored inside the relevant variant of the `TicketNewError` enum. // stored inside the relevant variant of the `TicketNewError` enum.
// When the description is invalid, instead, it should use a default description: // When the description is invalid, instead, it should use a default description:
// "Description not provided". // "Description not provided".
fn easy_ticket(title: String, description: String, status: Status) -> Ticket { 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)] #[derive(Debug, PartialEq)]
@@ -32,16 +45,24 @@ impl Ticket {
status: Status, status: Status,
) -> Result<Ticket, TicketNewError> { ) -> Result<Ticket, TicketNewError> {
if title.is_empty() { 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 { 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() { 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 { 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 { Ok(Ticket {

View File

@@ -3,17 +3,41 @@
// The docs for the `std::fmt` module are a good place to start and look for examples: // 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 // https://doc.rust-lang.org/std/fmt/index.html#write
use std::error::Error;
use std::fmt::{Display, Formatter};
#[derive(Debug)]
enum TicketNewError { enum TicketNewError {
TitleError(String), TitleError(String),
DescriptionError(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 // TODO: `easy_ticket` should panic when the title is invalid, using the error message
// stored inside the relevant variant of the `TicketNewError` enum. // stored inside the relevant variant of the `TicketNewError` enum.
// When the description is invalid, instead, it should use a default description: // When the description is invalid, instead, it should use a default description:
// "Description not provided". // "Description not provided".
fn easy_ticket(title: String, description: String, status: Status) -> Ticket { 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)] #[derive(Debug, PartialEq, Clone)]

View File

@@ -0,0 +1 @@
pub fn hello_world() {}

View File

@@ -2,3 +2,6 @@
name = "deps" name = "deps"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
[dependencies]
anyhow = "*"

View File

@@ -4,6 +4,6 @@ version = "0.1.0"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
thiserror = "*"
[dev-dependencies] [dev-dependencies]
common = { path = "../../../helpers/common" } common = { path = "../../../helpers/common" }

View File

@@ -3,10 +3,17 @@
// a `String` field into each variant. // a `String` field into each variant.
// You'll also have to add `thiserror` as a dependency in the `Cargo.toml` file. // You'll also have to add `thiserror` as a dependency in the `Cargo.toml` file.
use thiserror::Error;
#[derive(thiserror::Error, Debug)]
enum TicketNewError { enum TicketNewError {
#[error("Title cannot be empty")]
TitleCannotBeEmpty, TitleCannotBeEmpty,
#[error("Title cannot be longer than 50 bytes")]
TitleTooLong, TitleTooLong,
#[error("Description cannot be empty")]
DescriptionCannotBeEmpty, DescriptionCannotBeEmpty,
#[error("Description cannot be longer than 500 bytes")]
DescriptionTooLong, DescriptionTooLong,
} }