completed most of 05 ticket v2
This commit is contained in:
6
Cargo.lock
generated
6
Cargo.lock
generated
@@ -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]]
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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)]
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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)]
|
||||||
|
|||||||
1
exercises/05_ticket_v2/10_packages/src/lib.rs
Normal file
1
exercises/05_ticket_v2/10_packages/src/lib.rs
Normal file
@@ -0,0 +1 @@
|
|||||||
|
pub fn hello_world() {}
|
||||||
@@ -2,3 +2,6 @@
|
|||||||
name = "deps"
|
name = "deps"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
anyhow = "*"
|
||||||
|
|||||||
@@ -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" }
|
||||||
|
|||||||
@@ -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,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user