initial commit
This commit is contained in:
4
exercises/06_ticket_management/00_intro/Cargo.toml
Normal file
4
exercises/06_ticket_management/00_intro/Cargo.toml
Normal file
@@ -0,0 +1,4 @@
|
||||
[package]
|
||||
name = "intro_05"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
14
exercises/06_ticket_management/00_intro/src/lib.rs
Normal file
14
exercises/06_ticket_management/00_intro/src/lib.rs
Normal file
@@ -0,0 +1,14 @@
|
||||
fn intro() -> &'static str {
|
||||
// TODO: fix me 👇
|
||||
"I'm ready to __!"
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::intro;
|
||||
|
||||
#[test]
|
||||
fn test_intro() {
|
||||
assert_eq!(intro(), "I'm ready to build a ticket management system!");
|
||||
}
|
||||
}
|
||||
4
exercises/06_ticket_management/01_arrays/Cargo.toml
Normal file
4
exercises/06_ticket_management/01_arrays/Cargo.toml
Normal file
@@ -0,0 +1,4 @@
|
||||
[package]
|
||||
name = "arrays"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
80
exercises/06_ticket_management/01_arrays/src/lib.rs
Normal file
80
exercises/06_ticket_management/01_arrays/src/lib.rs
Normal file
@@ -0,0 +1,80 @@
|
||||
// TODO: Flesh out the `WeekTemperatures` struct and its method implementations to pass the tests.
|
||||
|
||||
pub struct WeekTemperatures {
|
||||
// TODO
|
||||
}
|
||||
|
||||
pub enum Weekday {
|
||||
Monday,
|
||||
Tuesday,
|
||||
Wednesday,
|
||||
Thursday,
|
||||
Friday,
|
||||
Saturday,
|
||||
Sunday,
|
||||
}
|
||||
|
||||
impl WeekTemperatures {
|
||||
pub fn new() -> Self {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn get_temperature(&self, day: Weekday) -> Option<i32> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn set_temperature(&mut self, day: Weekday, temperature: i32) {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_get_temperature() {
|
||||
let mut week_temperatures = WeekTemperatures::new();
|
||||
|
||||
assert_eq!(week_temperatures.get_temperature(Weekday::Monday), None);
|
||||
assert_eq!(week_temperatures.get_temperature(Weekday::Tuesday), None);
|
||||
assert_eq!(week_temperatures.get_temperature(Weekday::Wednesday), None);
|
||||
assert_eq!(week_temperatures.get_temperature(Weekday::Thursday), None);
|
||||
assert_eq!(week_temperatures.get_temperature(Weekday::Friday), None);
|
||||
assert_eq!(week_temperatures.get_temperature(Weekday::Saturday), None);
|
||||
assert_eq!(week_temperatures.get_temperature(Weekday::Sunday), None);
|
||||
|
||||
week_temperatures.set_temperature(Weekday::Monday, 20);
|
||||
assert_eq!(week_temperatures.get_temperature(Weekday::Monday), Some(20));
|
||||
|
||||
week_temperatures.set_temperature(Weekday::Monday, 25);
|
||||
assert_eq!(week_temperatures.get_temperature(Weekday::Monday), Some(25));
|
||||
|
||||
week_temperatures.set_temperature(Weekday::Tuesday, 30);
|
||||
week_temperatures.set_temperature(Weekday::Wednesday, 35);
|
||||
week_temperatures.set_temperature(Weekday::Thursday, 40);
|
||||
week_temperatures.set_temperature(Weekday::Friday, 45);
|
||||
week_temperatures.set_temperature(Weekday::Saturday, 50);
|
||||
week_temperatures.set_temperature(Weekday::Sunday, 55);
|
||||
|
||||
assert_eq!(week_temperatures.get_temperature(Weekday::Monday), Some(25));
|
||||
assert_eq!(
|
||||
week_temperatures.get_temperature(Weekday::Tuesday),
|
||||
Some(30)
|
||||
);
|
||||
assert_eq!(
|
||||
week_temperatures.get_temperature(Weekday::Wednesday),
|
||||
Some(35)
|
||||
);
|
||||
assert_eq!(
|
||||
week_temperatures.get_temperature(Weekday::Thursday),
|
||||
Some(40)
|
||||
);
|
||||
assert_eq!(week_temperatures.get_temperature(Weekday::Friday), Some(45));
|
||||
assert_eq!(
|
||||
week_temperatures.get_temperature(Weekday::Saturday),
|
||||
Some(50)
|
||||
);
|
||||
assert_eq!(week_temperatures.get_temperature(Weekday::Sunday), Some(55));
|
||||
}
|
||||
}
|
||||
4
exercises/06_ticket_management/02_vec/Cargo.toml
Normal file
4
exercises/06_ticket_management/02_vec/Cargo.toml
Normal file
@@ -0,0 +1,4 @@
|
||||
[package]
|
||||
name = "vec"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
49
exercises/06_ticket_management/02_vec/src/lib.rs
Normal file
49
exercises/06_ticket_management/02_vec/src/lib.rs
Normal file
@@ -0,0 +1,49 @@
|
||||
// Given a number `n`, return the `n+1`th number in the Fibonacci sequence.
|
||||
//
|
||||
// The Fibonacci sequence is defined as follows:
|
||||
//
|
||||
// - The first number of the sequence is 0.
|
||||
// - The second number of the sequence is 1.
|
||||
// - Every subsequent number is the sum of the two preceding numbers.
|
||||
//
|
||||
// So the sequence goes: 0, 1, 1, 2, 3, 5, 8, 13, 21, and so on.
|
||||
//
|
||||
// We expect `fibonacci(0)` to return `0`, `fibonacci(1)` to return `1`,
|
||||
// `fibonacci(2)` to return `1`, and so on.
|
||||
pub fn fibonacci(n: u32) -> u32 {
|
||||
// TODO: implement the `fibonacci` function
|
||||
//
|
||||
// Hint: use a `Vec` to memoize the results you have already calculated
|
||||
// so that you don't have to recalculate them several times.
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::fibonacci;
|
||||
|
||||
#[test]
|
||||
fn first() {
|
||||
assert_eq!(fibonacci(0), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn second() {
|
||||
assert_eq!(fibonacci(1), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn third() {
|
||||
assert_eq!(fibonacci(2), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tenth() {
|
||||
assert_eq!(fibonacci(10), 55);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn thirtieth() {
|
||||
assert_eq!(fibonacci(30), 832040);
|
||||
}
|
||||
}
|
||||
4
exercises/06_ticket_management/03_resizing/Cargo.toml
Normal file
4
exercises/06_ticket_management/03_resizing/Cargo.toml
Normal file
@@ -0,0 +1,4 @@
|
||||
[package]
|
||||
name = "resizing"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
17
exercises/06_ticket_management/03_resizing/src/lib.rs
Normal file
17
exercises/06_ticket_management/03_resizing/src/lib.rs
Normal file
@@ -0,0 +1,17 @@
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn resizing() {
|
||||
let mut v = Vec::with_capacity(2);
|
||||
v.push(1);
|
||||
v.push(2); // max capacity reached
|
||||
assert_eq!(v.capacity(), 2);
|
||||
|
||||
v.push(3); // beyond capacity, needs to resize
|
||||
|
||||
// Can you guess what the new capacity will be?
|
||||
// Beware that the standard library makes no guarantees about the
|
||||
// algorithm used to resize the vector, so this may change in the future.
|
||||
assert_eq!(v.capacity(), todo!());
|
||||
}
|
||||
}
|
||||
7
exercises/06_ticket_management/04_iterators/Cargo.toml
Normal file
7
exercises/06_ticket_management/04_iterators/Cargo.toml
Normal file
@@ -0,0 +1,7 @@
|
||||
[package]
|
||||
name = "iterators"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
ticket_fields = { path = "../../../helpers/ticket_fields" }
|
||||
68
exercises/06_ticket_management/04_iterators/src/lib.rs
Normal file
68
exercises/06_ticket_management/04_iterators/src/lib.rs
Normal file
@@ -0,0 +1,68 @@
|
||||
use ticket_fields::{TicketDescription, TicketTitle};
|
||||
|
||||
// TODO: Let's start sketching our ticket store!
|
||||
// First task: implement `IntoIterator` on `TicketStore` to allow iterating over all the tickets
|
||||
// it contains using a `for` loop.
|
||||
//
|
||||
// Hint: you shouldn't have to implement the `Iterator` trait in this case.
|
||||
// You want to *delegate* the iteration to the `Vec<Ticket>` field in `TicketStore`.
|
||||
// Look at the standard library documentation for `Vec` to find the right type
|
||||
// to return from `into_iter`.
|
||||
#[derive(Clone)]
|
||||
pub struct TicketStore {
|
||||
tickets: Vec<Ticket>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Ticket {
|
||||
pub title: TicketTitle,
|
||||
pub description: TicketDescription,
|
||||
pub status: Status,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Copy, PartialEq)]
|
||||
pub enum Status {
|
||||
ToDo,
|
||||
InProgress,
|
||||
Done,
|
||||
}
|
||||
|
||||
impl TicketStore {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
tickets: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_ticket(&mut self, ticket: Ticket) {
|
||||
self.tickets.push(ticket);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use ticket_fields::test_helpers::{ticket_description, ticket_title};
|
||||
|
||||
#[test]
|
||||
fn add_ticket() {
|
||||
let mut store = TicketStore::new();
|
||||
|
||||
let ticket = Ticket {
|
||||
title: ticket_title(),
|
||||
description: ticket_description(),
|
||||
status: Status::ToDo,
|
||||
};
|
||||
store.add_ticket(ticket);
|
||||
|
||||
let ticket = Ticket {
|
||||
title: ticket_title(),
|
||||
description: ticket_description(),
|
||||
status: Status::InProgress,
|
||||
};
|
||||
store.add_ticket(ticket);
|
||||
|
||||
let tickets: Vec<_> = store.clone().into_iter().collect();
|
||||
assert_eq!(tickets, store.tickets);
|
||||
}
|
||||
}
|
||||
7
exercises/06_ticket_management/05_iter/Cargo.toml
Normal file
7
exercises/06_ticket_management/05_iter/Cargo.toml
Normal file
@@ -0,0 +1,7 @@
|
||||
[package]
|
||||
name = "iter"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
ticket_fields = { path = "../../../helpers/ticket_fields" }
|
||||
66
exercises/06_ticket_management/05_iter/src/lib.rs
Normal file
66
exercises/06_ticket_management/05_iter/src/lib.rs
Normal file
@@ -0,0 +1,66 @@
|
||||
use ticket_fields::{TicketDescription, TicketTitle};
|
||||
|
||||
// TODO: Provide an `iter` method that returns an iterator over `&Ticket` items.
|
||||
//
|
||||
// Hint: just like in the previous exercise, you want to delegate the iteration to
|
||||
// the `Vec<Ticket>` field in `TicketStore`. Look at the standard library documentation
|
||||
// for `Vec` to find the right type to return from `iter`.
|
||||
#[derive(Clone)]
|
||||
pub struct TicketStore {
|
||||
tickets: Vec<Ticket>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct Ticket {
|
||||
title: TicketTitle,
|
||||
description: TicketDescription,
|
||||
status: Status,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Copy, PartialEq)]
|
||||
pub enum Status {
|
||||
ToDo,
|
||||
InProgress,
|
||||
Done,
|
||||
}
|
||||
|
||||
impl TicketStore {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
tickets: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_ticket(&mut self, ticket: Ticket) {
|
||||
self.tickets.push(ticket);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use ticket_fields::test_helpers::{ticket_description, ticket_title};
|
||||
|
||||
#[test]
|
||||
fn add_ticket() {
|
||||
let mut store = TicketStore::new();
|
||||
|
||||
let ticket = Ticket {
|
||||
title: ticket_title(),
|
||||
description: ticket_description(),
|
||||
status: Status::ToDo,
|
||||
};
|
||||
store.add_ticket(ticket);
|
||||
|
||||
let ticket = Ticket {
|
||||
title: ticket_title(),
|
||||
description: ticket_description(),
|
||||
status: Status::InProgress,
|
||||
};
|
||||
store.add_ticket(ticket);
|
||||
|
||||
let tickets: Vec<&Ticket> = store.iter().collect();
|
||||
let tickets2: Vec<&Ticket> = store.iter().collect();
|
||||
assert_eq!(tickets, tickets2);
|
||||
}
|
||||
}
|
||||
7
exercises/06_ticket_management/06_lifetimes/Cargo.toml
Normal file
7
exercises/06_ticket_management/06_lifetimes/Cargo.toml
Normal file
@@ -0,0 +1,7 @@
|
||||
[package]
|
||||
name = "lifetime"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
ticket_fields = { path = "../../../helpers/ticket_fields" }
|
||||
66
exercises/06_ticket_management/06_lifetimes/src/lib.rs
Normal file
66
exercises/06_ticket_management/06_lifetimes/src/lib.rs
Normal file
@@ -0,0 +1,66 @@
|
||||
use ticket_fields::{TicketDescription, TicketTitle};
|
||||
|
||||
// TODO: Implement the `IntoIterator` trait for `&TicketStore` so that the test compiles and passes.
|
||||
#[derive(Clone)]
|
||||
pub struct TicketStore {
|
||||
tickets: Vec<Ticket>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Ticket {
|
||||
pub title: TicketTitle,
|
||||
pub description: TicketDescription,
|
||||
pub status: Status,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Copy, PartialEq)]
|
||||
pub enum Status {
|
||||
ToDo,
|
||||
InProgress,
|
||||
Done,
|
||||
}
|
||||
|
||||
impl TicketStore {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
tickets: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_ticket(&mut self, ticket: Ticket) {
|
||||
self.tickets.push(ticket);
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> std::slice::Iter<Ticket> {
|
||||
self.tickets.iter()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use ticket_fields::test_helpers::{ticket_description, ticket_title};
|
||||
|
||||
#[test]
|
||||
fn add_ticket() {
|
||||
let mut store = TicketStore::new();
|
||||
|
||||
let ticket = Ticket {
|
||||
title: ticket_title(),
|
||||
description: ticket_description(),
|
||||
status: Status::ToDo,
|
||||
};
|
||||
store.add_ticket(ticket);
|
||||
|
||||
let ticket = Ticket {
|
||||
title: ticket_title(),
|
||||
description: ticket_description(),
|
||||
status: Status::InProgress,
|
||||
};
|
||||
store.add_ticket(ticket);
|
||||
|
||||
let tickets: Vec<&Ticket> = store.iter().collect();
|
||||
let tickets2: Vec<&Ticket> = (&store).into_iter().collect();
|
||||
assert_eq!(tickets, tickets2);
|
||||
}
|
||||
}
|
||||
7
exercises/06_ticket_management/07_combinators/Cargo.toml
Normal file
7
exercises/06_ticket_management/07_combinators/Cargo.toml
Normal file
@@ -0,0 +1,7 @@
|
||||
[package]
|
||||
name = "combinators"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
ticket_fields = { path = "../../../helpers/ticket_fields" }
|
||||
63
exercises/06_ticket_management/07_combinators/src/lib.rs
Normal file
63
exercises/06_ticket_management/07_combinators/src/lib.rs
Normal file
@@ -0,0 +1,63 @@
|
||||
// TODO: Implement the `to_dos` method. It must return a `Vec` of references to the tickets
|
||||
// in `TicketStore` with status set to `Status::ToDo`.
|
||||
use ticket_fields::{TicketDescription, TicketTitle};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct TicketStore {
|
||||
tickets: Vec<Ticket>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Ticket {
|
||||
pub title: TicketTitle,
|
||||
pub description: TicketDescription,
|
||||
pub status: Status,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Copy, PartialEq)]
|
||||
pub enum Status {
|
||||
ToDo,
|
||||
InProgress,
|
||||
Done,
|
||||
}
|
||||
|
||||
impl TicketStore {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
tickets: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_ticket(&mut self, ticket: Ticket) {
|
||||
self.tickets.push(ticket);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use ticket_fields::test_helpers::{ticket_description, ticket_title};
|
||||
|
||||
#[test]
|
||||
fn todos() {
|
||||
let mut store = TicketStore::new();
|
||||
|
||||
let todo = Ticket {
|
||||
title: ticket_title(),
|
||||
description: ticket_description(),
|
||||
status: Status::ToDo,
|
||||
};
|
||||
store.add_ticket(todo.clone());
|
||||
|
||||
let ticket = Ticket {
|
||||
title: ticket_title(),
|
||||
description: ticket_description(),
|
||||
status: Status::InProgress,
|
||||
};
|
||||
store.add_ticket(ticket);
|
||||
|
||||
let todos: Vec<&Ticket> = store.to_dos();
|
||||
assert_eq!(todos.len(), 1);
|
||||
assert_eq!(todos[0], &todo);
|
||||
}
|
||||
}
|
||||
7
exercises/06_ticket_management/08_impl_trait/Cargo.toml
Normal file
7
exercises/06_ticket_management/08_impl_trait/Cargo.toml
Normal file
@@ -0,0 +1,7 @@
|
||||
[package]
|
||||
name = "impl_trait"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
ticket_fields = { path = "../../../helpers/ticket_fields" }
|
||||
63
exercises/06_ticket_management/08_impl_trait/src/lib.rs
Normal file
63
exercises/06_ticket_management/08_impl_trait/src/lib.rs
Normal file
@@ -0,0 +1,63 @@
|
||||
// TODO: Implement the `in_progress` method. It must return an iterator over the tickets in
|
||||
// `TicketStore` with status set to `Status::InProgress`.
|
||||
use ticket_fields::{TicketDescription, TicketTitle};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct TicketStore {
|
||||
tickets: Vec<Ticket>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Ticket {
|
||||
pub title: TicketTitle,
|
||||
pub description: TicketDescription,
|
||||
pub status: Status,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Copy, PartialEq)]
|
||||
pub enum Status {
|
||||
ToDo,
|
||||
InProgress,
|
||||
Done,
|
||||
}
|
||||
|
||||
impl TicketStore {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
tickets: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_ticket(&mut self, ticket: Ticket) {
|
||||
self.tickets.push(ticket);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use ticket_fields::test_helpers::{ticket_description, ticket_title};
|
||||
|
||||
#[test]
|
||||
fn in_progress() {
|
||||
let mut store = TicketStore::new();
|
||||
|
||||
let todo = Ticket {
|
||||
title: ticket_title(),
|
||||
description: ticket_description(),
|
||||
status: Status::ToDo,
|
||||
};
|
||||
store.add_ticket(todo);
|
||||
|
||||
let in_progress = Ticket {
|
||||
title: ticket_title(),
|
||||
description: ticket_description(),
|
||||
status: Status::InProgress,
|
||||
};
|
||||
store.add_ticket(in_progress.clone());
|
||||
|
||||
let in_progress_tickets: Vec<&Ticket> = store.in_progress().collect();
|
||||
assert_eq!(in_progress_tickets.len(), 1);
|
||||
assert_eq!(in_progress_tickets[0], &in_progress);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
[package]
|
||||
name = "impl_trait_2"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
ticket_fields = { path = "../../../helpers/ticket_fields" }
|
||||
70
exercises/06_ticket_management/09_impl_trait_2/src/lib.rs
Normal file
70
exercises/06_ticket_management/09_impl_trait_2/src/lib.rs
Normal file
@@ -0,0 +1,70 @@
|
||||
// TODO: Rework the signature of `TicketStore::add_ticket` to use a generic type parameter rather
|
||||
// than `impl Trait` syntax.
|
||||
|
||||
use ticket_fields::{TicketDescription, TicketTitle};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct TicketStore {
|
||||
tickets: Vec<Ticket>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Ticket {
|
||||
pub title: TicketTitle,
|
||||
pub description: TicketDescription,
|
||||
pub status: Status,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Copy, PartialEq)]
|
||||
pub enum Status {
|
||||
ToDo,
|
||||
InProgress,
|
||||
Done,
|
||||
}
|
||||
|
||||
impl TicketStore {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
tickets: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
// Using `Into<Ticket>` as the type parameter for `ticket` allows the method to accept any type
|
||||
// that can be infallibly converted into a `Ticket`.
|
||||
// This can make it nicer to use the method, as it removes the syntax noise of `.into()`
|
||||
// from the calling site. It can worsen the quality of the compiler error messages, though.
|
||||
pub fn add_ticket(&mut self, ticket: impl Into<Ticket>) {
|
||||
self.tickets.push(ticket.into());
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use ticket_fields::test_helpers::{ticket_description, ticket_title};
|
||||
|
||||
struct TicketDraft {
|
||||
pub title: TicketTitle,
|
||||
pub description: TicketDescription,
|
||||
}
|
||||
|
||||
impl From<TicketDraft> for Ticket {
|
||||
fn from(draft: TicketDraft) -> Self {
|
||||
Self {
|
||||
title: draft.title,
|
||||
description: draft.description,
|
||||
status: Status::ToDo,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn generic_add() {
|
||||
let mut store = TicketStore::new();
|
||||
// This won't compile if `add_ticket` uses `impl Trait` syntax in argument position.
|
||||
store.add_ticket::<TicketDraft>(TicketDraft {
|
||||
title: ticket_title(),
|
||||
description: ticket_description(),
|
||||
});
|
||||
}
|
||||
}
|
||||
4
exercises/06_ticket_management/10_slices/Cargo.toml
Normal file
4
exercises/06_ticket_management/10_slices/Cargo.toml
Normal file
@@ -0,0 +1,4 @@
|
||||
[package]
|
||||
name = "slice"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
31
exercises/06_ticket_management/10_slices/src/lib.rs
Normal file
31
exercises/06_ticket_management/10_slices/src/lib.rs
Normal file
@@ -0,0 +1,31 @@
|
||||
// TODO: Define a function named `sum` that takes a reference to a slice of `u32` and returns the sum of all
|
||||
// elements in the slice.
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn empty() {
|
||||
let v = vec![];
|
||||
assert_eq!(sum(&v), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn one_element() {
|
||||
let v = vec![1];
|
||||
assert_eq!(sum(&v), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_elements() {
|
||||
let v = vec![1, 2, 3, 4, 5];
|
||||
assert_eq!(sum(&v), 15);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn array_slice() {
|
||||
let v = [1, 2, 3, 4, 5];
|
||||
assert_eq!(sum(&v), 15);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
[package]
|
||||
name = "mut_slice"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
28
exercises/06_ticket_management/11_mutable_slices/src/lib.rs
Normal file
28
exercises/06_ticket_management/11_mutable_slices/src/lib.rs
Normal file
@@ -0,0 +1,28 @@
|
||||
// TODO: Define a function named `squared` that raises all `i32`s within a slice to the power of 2.
|
||||
// The slice should be modified in place.
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn empty() {
|
||||
let mut s = vec![];
|
||||
squared(&mut s);
|
||||
assert_eq!(s, vec![]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn one() {
|
||||
let mut s = [2];
|
||||
squared(&mut s);
|
||||
assert_eq!(s, [4]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple() {
|
||||
let mut s = vec![2, 4];
|
||||
squared(&mut s);
|
||||
assert_eq!(s, vec![4, 16]);
|
||||
}
|
||||
}
|
||||
7
exercises/06_ticket_management/12_two_states/Cargo.toml
Normal file
7
exercises/06_ticket_management/12_two_states/Cargo.toml
Normal file
@@ -0,0 +1,7 @@
|
||||
[package]
|
||||
name = "two_states"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
ticket_fields = { path = "../../../helpers/ticket_fields" }
|
||||
80
exercises/06_ticket_management/12_two_states/src/lib.rs
Normal file
80
exercises/06_ticket_management/12_two_states/src/lib.rs
Normal file
@@ -0,0 +1,80 @@
|
||||
// TODO: Update `add_ticket`'s signature: it should take a `TicketDraft` as input
|
||||
// and return a `TicketId` as output.
|
||||
// Each ticket should have a unique id, generated by `TicketStore`.
|
||||
// Feel free to modify `TicketStore` fields, if needed.
|
||||
//
|
||||
// You also need to add a `get` method that takes as input a `TicketId`
|
||||
// and returns an `Option<&Ticket>`.
|
||||
|
||||
use ticket_fields::{TicketDescription, TicketTitle};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct TicketStore {
|
||||
tickets: Vec<Ticket>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub struct TicketId(u64);
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Ticket {
|
||||
pub id: TicketId,
|
||||
pub title: TicketTitle,
|
||||
pub description: TicketDescription,
|
||||
pub status: Status,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct TicketDraft {
|
||||
pub title: TicketTitle,
|
||||
pub description: TicketDescription,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Copy, PartialEq)]
|
||||
pub enum Status {
|
||||
ToDo,
|
||||
InProgress,
|
||||
Done,
|
||||
}
|
||||
|
||||
impl TicketStore {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
tickets: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_ticket(&mut self, ticket: Ticket) {
|
||||
self.tickets.push(ticket);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{Status, TicketDraft, TicketStore};
|
||||
use ticket_fields::test_helpers::{ticket_description, ticket_title};
|
||||
|
||||
#[test]
|
||||
fn works() {
|
||||
let mut store = TicketStore::new();
|
||||
|
||||
let draft1 = TicketDraft {
|
||||
title: ticket_title(),
|
||||
description: ticket_description(),
|
||||
};
|
||||
let id1 = store.add_ticket(draft1.clone());
|
||||
let ticket1 = store.get(id1).unwrap();
|
||||
assert_eq!(draft1.title, ticket1.title);
|
||||
assert_eq!(draft1.description, ticket1.description);
|
||||
assert_eq!(ticket1.status, Status::ToDo);
|
||||
|
||||
let draft2 = TicketDraft {
|
||||
title: ticket_title(),
|
||||
description: ticket_description(),
|
||||
};
|
||||
let id2 = store.add_ticket(draft2);
|
||||
let ticket2 = store.get(id2).unwrap();
|
||||
|
||||
assert_ne!(id1, id2);
|
||||
}
|
||||
}
|
||||
7
exercises/06_ticket_management/13_index/Cargo.toml
Normal file
7
exercises/06_ticket_management/13_index/Cargo.toml
Normal file
@@ -0,0 +1,7 @@
|
||||
[package]
|
||||
name = "index"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
ticket_fields = { path = "../../../helpers/ticket_fields" }
|
||||
89
exercises/06_ticket_management/13_index/src/lib.rs
Normal file
89
exercises/06_ticket_management/13_index/src/lib.rs
Normal file
@@ -0,0 +1,89 @@
|
||||
// TODO: Implement `Index<&TicketId>` and `Index<TicketId>` for `TicketStore`.
|
||||
|
||||
use ticket_fields::{TicketDescription, TicketTitle};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct TicketStore {
|
||||
tickets: Vec<Ticket>,
|
||||
counter: u64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub struct TicketId(u64);
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Ticket {
|
||||
pub id: TicketId,
|
||||
pub title: TicketTitle,
|
||||
pub description: TicketDescription,
|
||||
pub status: Status,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct TicketDraft {
|
||||
pub title: TicketTitle,
|
||||
pub description: TicketDescription,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Copy, PartialEq)]
|
||||
pub enum Status {
|
||||
ToDo,
|
||||
InProgress,
|
||||
Done,
|
||||
}
|
||||
|
||||
impl TicketStore {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
tickets: Vec::new(),
|
||||
counter: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_ticket(&mut self, ticket: TicketDraft) -> TicketId {
|
||||
let id = TicketId(self.counter);
|
||||
self.counter += 1;
|
||||
let ticket = Ticket {
|
||||
id,
|
||||
title: ticket.title,
|
||||
description: ticket.description,
|
||||
status: Status::ToDo,
|
||||
};
|
||||
self.tickets.push(ticket);
|
||||
id
|
||||
}
|
||||
|
||||
pub fn get(&self, id: TicketId) -> Option<&Ticket> {
|
||||
self.tickets.iter().find(|&t| t.id == id)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{Status, TicketDraft, TicketStore};
|
||||
use ticket_fields::test_helpers::{ticket_description, ticket_title};
|
||||
|
||||
#[test]
|
||||
fn works() {
|
||||
let mut store = TicketStore::new();
|
||||
|
||||
let draft1 = TicketDraft {
|
||||
title: ticket_title(),
|
||||
description: ticket_description(),
|
||||
};
|
||||
let id1 = store.add_ticket(draft1.clone());
|
||||
let ticket1 = &store[id1];
|
||||
assert_eq!(draft1.title, ticket1.title);
|
||||
assert_eq!(draft1.description, ticket1.description);
|
||||
assert_eq!(ticket1.status, Status::ToDo);
|
||||
|
||||
let draft2 = TicketDraft {
|
||||
title: ticket_title(),
|
||||
description: ticket_description(),
|
||||
};
|
||||
let id2 = store.add_ticket(draft2);
|
||||
let ticket2 = &store[&id2];
|
||||
|
||||
assert_ne!(id1, id2);
|
||||
}
|
||||
}
|
||||
7
exercises/06_ticket_management/14_index_mut/Cargo.toml
Normal file
7
exercises/06_ticket_management/14_index_mut/Cargo.toml
Normal file
@@ -0,0 +1,7 @@
|
||||
[package]
|
||||
name = "index_mut"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
ticket_fields = { path = "../../../helpers/ticket_fields" }
|
||||
109
exercises/06_ticket_management/14_index_mut/src/lib.rs
Normal file
109
exercises/06_ticket_management/14_index_mut/src/lib.rs
Normal file
@@ -0,0 +1,109 @@
|
||||
// TODO: Implement `IndexMut<&TicketId>` and `IndexMut<TicketId>` for `TicketStore`.
|
||||
|
||||
use std::ops::Index;
|
||||
use ticket_fields::{TicketDescription, TicketTitle};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct TicketStore {
|
||||
tickets: Vec<Ticket>,
|
||||
counter: u64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub struct TicketId(u64);
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Ticket {
|
||||
pub id: TicketId,
|
||||
pub title: TicketTitle,
|
||||
pub description: TicketDescription,
|
||||
pub status: Status,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct TicketDraft {
|
||||
pub title: TicketTitle,
|
||||
pub description: TicketDescription,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Copy, PartialEq)]
|
||||
pub enum Status {
|
||||
ToDo,
|
||||
InProgress,
|
||||
Done,
|
||||
}
|
||||
|
||||
impl TicketStore {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
tickets: Vec::new(),
|
||||
counter: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_ticket(&mut self, ticket: TicketDraft) -> TicketId {
|
||||
let id = TicketId(self.counter);
|
||||
self.counter += 1;
|
||||
let ticket = Ticket {
|
||||
id,
|
||||
title: ticket.title,
|
||||
description: ticket.description,
|
||||
status: Status::ToDo,
|
||||
};
|
||||
self.tickets.push(ticket);
|
||||
id
|
||||
}
|
||||
|
||||
pub fn get(&self, id: TicketId) -> Option<&Ticket> {
|
||||
self.tickets.iter().find(|&t| t.id == id)
|
||||
}
|
||||
}
|
||||
|
||||
impl Index<TicketId> for TicketStore {
|
||||
type Output = Ticket;
|
||||
|
||||
fn index(&self, index: TicketId) -> &Self::Output {
|
||||
self.get(index).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl Index<&TicketId> for TicketStore {
|
||||
type Output = Ticket;
|
||||
|
||||
fn index(&self, index: &TicketId) -> &Self::Output {
|
||||
&self[*index]
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{Status, TicketDraft, TicketStore};
|
||||
use ticket_fields::test_helpers::{ticket_description, ticket_title};
|
||||
|
||||
#[test]
|
||||
fn works() {
|
||||
let mut store = TicketStore::new();
|
||||
|
||||
let draft = TicketDraft {
|
||||
title: ticket_title(),
|
||||
description: ticket_description(),
|
||||
};
|
||||
let id = store.add_ticket(draft.clone());
|
||||
let ticket = &store[id];
|
||||
assert_eq!(draft.title, ticket.title);
|
||||
assert_eq!(draft.description, ticket.description);
|
||||
assert_eq!(ticket.status, Status::ToDo);
|
||||
|
||||
let ticket = &mut store[id];
|
||||
ticket.status = Status::InProgress;
|
||||
|
||||
let ticket = &store[id];
|
||||
assert_eq!(ticket.status, Status::InProgress);
|
||||
|
||||
let ticket = &mut store[&id];
|
||||
ticket.status = Status::Done;
|
||||
|
||||
let ticket = &store[id];
|
||||
assert_eq!(ticket.status, Status::Done);
|
||||
}
|
||||
}
|
||||
7
exercises/06_ticket_management/15_hashmap/Cargo.toml
Normal file
7
exercises/06_ticket_management/15_hashmap/Cargo.toml
Normal file
@@ -0,0 +1,7 @@
|
||||
[package]
|
||||
name = "hashmap"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
ticket_fields = { path = "../../../helpers/ticket_fields" }
|
||||
121
exercises/06_ticket_management/15_hashmap/src/lib.rs
Normal file
121
exercises/06_ticket_management/15_hashmap/src/lib.rs
Normal file
@@ -0,0 +1,121 @@
|
||||
// TODO: Replace `todo!()`s with the correct implementation.
|
||||
// Implement additional traits on `TicketId` if needed.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::ops::{Index, IndexMut};
|
||||
use ticket_fields::{TicketDescription, TicketTitle};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct TicketStore {
|
||||
tickets: HashMap<TicketId, Ticket>,
|
||||
counter: u64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub struct TicketId(u64);
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Ticket {
|
||||
pub id: TicketId,
|
||||
pub title: TicketTitle,
|
||||
pub description: TicketDescription,
|
||||
pub status: Status,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct TicketDraft {
|
||||
pub title: TicketTitle,
|
||||
pub description: TicketDescription,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Copy, PartialEq, Eq)]
|
||||
pub enum Status {
|
||||
ToDo,
|
||||
InProgress,
|
||||
Done,
|
||||
}
|
||||
|
||||
impl TicketStore {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
tickets: todo!(),
|
||||
counter: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_ticket(&mut self, ticket: TicketDraft) -> TicketId {
|
||||
let id = TicketId(self.counter);
|
||||
self.counter += 1;
|
||||
let ticket = Ticket {
|
||||
id,
|
||||
title: ticket.title,
|
||||
description: ticket.description,
|
||||
status: Status::ToDo,
|
||||
};
|
||||
todo!();
|
||||
id
|
||||
}
|
||||
|
||||
pub fn get(&self, id: TicketId) -> Option<&Ticket> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn get_mut(&mut self, id: TicketId) -> Option<&mut Ticket> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl Index<TicketId> for TicketStore {
|
||||
type Output = Ticket;
|
||||
|
||||
fn index(&self, index: TicketId) -> &Self::Output {
|
||||
self.get(index).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl Index<&TicketId> for TicketStore {
|
||||
type Output = Ticket;
|
||||
|
||||
fn index(&self, index: &TicketId) -> &Self::Output {
|
||||
&self[*index]
|
||||
}
|
||||
}
|
||||
|
||||
impl IndexMut<TicketId> for TicketStore {
|
||||
fn index_mut(&mut self, index: TicketId) -> &mut Self::Output {
|
||||
self.get_mut(index).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl IndexMut<&TicketId> for TicketStore {
|
||||
fn index_mut(&mut self, index: &TicketId) -> &mut Self::Output {
|
||||
&mut self[*index]
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{Status, TicketDraft, TicketStore};
|
||||
use ticket_fields::test_helpers::{ticket_description, ticket_title};
|
||||
|
||||
#[test]
|
||||
fn works() {
|
||||
let mut store = TicketStore::new();
|
||||
|
||||
let draft = TicketDraft {
|
||||
title: ticket_title(),
|
||||
description: ticket_description(),
|
||||
};
|
||||
let id = store.add_ticket(draft.clone());
|
||||
let ticket = &store[id];
|
||||
assert_eq!(draft.title, ticket.title);
|
||||
assert_eq!(draft.description, ticket.description);
|
||||
assert_eq!(ticket.status, Status::ToDo);
|
||||
|
||||
let ticket = &mut store[id];
|
||||
ticket.status = Status::InProgress;
|
||||
|
||||
let ticket = &store[id];
|
||||
assert_eq!(ticket.status, Status::InProgress);
|
||||
}
|
||||
}
|
||||
7
exercises/06_ticket_management/16_btreemap/Cargo.toml
Normal file
7
exercises/06_ticket_management/16_btreemap/Cargo.toml
Normal file
@@ -0,0 +1,7 @@
|
||||
[package]
|
||||
name = "btreemap"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
ticket_fields = { path = "../../../helpers/ticket_fields" }
|
||||
135
exercises/06_ticket_management/16_btreemap/src/lib.rs
Normal file
135
exercises/06_ticket_management/16_btreemap/src/lib.rs
Normal file
@@ -0,0 +1,135 @@
|
||||
// TODO: Replace `todo!()`s with the correct implementation.
|
||||
// Implement `IntoIterator` for `&TicketStore`. The iterator should yield immutable
|
||||
// references to the tickets, ordered by their `TicketId`.
|
||||
// Implement additional traits on `TicketId` if needed.
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use std::ops::{Index, IndexMut};
|
||||
use ticket_fields::{TicketDescription, TicketTitle};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct TicketStore {
|
||||
tickets: BTreeMap<TicketId, Ticket>,
|
||||
counter: u64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub struct TicketId(u64);
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Ticket {
|
||||
pub id: TicketId,
|
||||
pub title: TicketTitle,
|
||||
pub description: TicketDescription,
|
||||
pub status: Status,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct TicketDraft {
|
||||
pub title: TicketTitle,
|
||||
pub description: TicketDescription,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Copy, PartialEq, Eq)]
|
||||
pub enum Status {
|
||||
ToDo,
|
||||
InProgress,
|
||||
Done,
|
||||
}
|
||||
|
||||
impl TicketStore {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
tickets: todo!(),
|
||||
counter: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_ticket(&mut self, ticket: TicketDraft) -> TicketId {
|
||||
let id = TicketId(self.counter);
|
||||
self.counter += 1;
|
||||
let ticket = Ticket {
|
||||
id,
|
||||
title: ticket.title,
|
||||
description: ticket.description,
|
||||
status: Status::ToDo,
|
||||
};
|
||||
todo!();
|
||||
id
|
||||
}
|
||||
|
||||
pub fn get(&self, id: TicketId) -> Option<&Ticket> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn get_mut(&mut self, id: TicketId) -> Option<&mut Ticket> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl Index<TicketId> for TicketStore {
|
||||
type Output = Ticket;
|
||||
|
||||
fn index(&self, index: TicketId) -> &Self::Output {
|
||||
self.get(index).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl Index<&TicketId> for TicketStore {
|
||||
type Output = Ticket;
|
||||
|
||||
fn index(&self, index: &TicketId) -> &Self::Output {
|
||||
&self[*index]
|
||||
}
|
||||
}
|
||||
|
||||
impl IndexMut<TicketId> for TicketStore {
|
||||
fn index_mut(&mut self, index: TicketId) -> &mut Self::Output {
|
||||
self.get_mut(index).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl IndexMut<&TicketId> for TicketStore {
|
||||
fn index_mut(&mut self, index: &TicketId) -> &mut Self::Output {
|
||||
&mut self[*index]
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{Status, TicketDraft, TicketId, TicketStore};
|
||||
use ticket_fields::test_helpers::{ticket_description, ticket_title};
|
||||
|
||||
#[test]
|
||||
fn works() {
|
||||
let mut store = TicketStore::new();
|
||||
|
||||
let n_tickets = 5;
|
||||
|
||||
for i in 0..n_tickets {
|
||||
let draft = TicketDraft {
|
||||
title: ticket_title(),
|
||||
description: ticket_description(),
|
||||
};
|
||||
let id = store.add_ticket(draft.clone());
|
||||
let ticket = &store[id];
|
||||
assert_eq!(draft.title, ticket.title);
|
||||
assert_eq!(draft.description, ticket.description);
|
||||
assert_eq!(ticket.status, Status::ToDo);
|
||||
|
||||
let ticket = &mut store[id];
|
||||
ticket.status = Status::InProgress;
|
||||
|
||||
let ticket = &store[id];
|
||||
assert_eq!(ticket.status, Status::InProgress);
|
||||
}
|
||||
|
||||
let ids: Vec<TicketId> = (&store).into_iter().map(|t| t.id).collect();
|
||||
let sorted_ids = {
|
||||
let mut v = ids.clone();
|
||||
v.sort();
|
||||
v
|
||||
};
|
||||
assert_eq!(ids, sorted_ids);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user