aboutsummaryrefslogtreecommitdiff
path: root/rust
diff options
context:
space:
mode:
Diffstat (limited to 'rust')
-rw-r--r--rust/grade-school/.exercism/metadata.json1
-rw-r--r--rust/grade-school/.gitignore8
-rw-r--r--rust/grade-school/Cargo.toml4
-rw-r--r--rust/grade-school/README.md118
-rw-r--r--rust/grade-school/src/lib.rs22
-rw-r--r--rust/grade-school/tests/grade-school.rs75
6 files changed, 228 insertions, 0 deletions
diff --git a/rust/grade-school/.exercism/metadata.json b/rust/grade-school/.exercism/metadata.json
new file mode 100644
index 0000000..2e6d20b
--- /dev/null
+++ b/rust/grade-school/.exercism/metadata.json
@@ -0,0 +1 @@
{"track":"rust","exercise":"grade-school","id":"7a8d0123d5884f6d8d1b5e3e6fad84b3","url":"https://exercism.io/my/solutions/7a8d0123d5884f6d8d1b5e3e6fad84b3","handle":"dyamon","is_requester":true,"auto_approve":false} \ No newline at end of file
diff --git a/rust/grade-school/.gitignore b/rust/grade-school/.gitignore
new file mode 100644
index 0000000..db7f315
--- /dev/null
+++ b/rust/grade-school/.gitignore
@@ -0,0 +1,8 @@
1# Generated by Cargo
2# will have compiled files and executables
3/target/
4**/*.rs.bk
5
6# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
7# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock
8Cargo.lock
diff --git a/rust/grade-school/Cargo.toml b/rust/grade-school/Cargo.toml
new file mode 100644
index 0000000..43ad344
--- /dev/null
+++ b/rust/grade-school/Cargo.toml
@@ -0,0 +1,4 @@
1[package]
2edition = "2018"
3name = "grade-school"
4version = "0.0.0"
diff --git a/rust/grade-school/README.md b/rust/grade-school/README.md
new file mode 100644
index 0000000..d93acd1
--- /dev/null
+++ b/rust/grade-school/README.md
@@ -0,0 +1,118 @@
1# Grade School
2
3Given students' names along with the grade that they are in, create a roster
4for the school.
5
6In the end, you should be able to:
7
8- Add a student's name to the roster for a grade
9 - "Add Jim to grade 2."
10 - "OK."
11- Get a list of all students enrolled in a grade
12 - "Which students are in grade 2?"
13 - "We've only got Jim just now."
14- Get a sorted list of all students in all grades. Grades should sort
15 as 1, 2, 3, etc., and students within a grade should be sorted
16 alphabetically by name.
17 - "Who all is enrolled in school right now?"
18 - "Let me think. We have
19 Anna, Barb, and Charlie in grade 1,
20 Alex, Peter, and Zoe in grade 2
21 and Jim in grade 5.
22 So the answer is: Anna, Barb, Charlie, Alex, Peter, Zoe and Jim"
23
24Note that all our students only have one name. (It's a small town, what
25do you want?)
26
27## For bonus points
28
29Did you get the tests passing and the code clean? If you want to, these
30are some additional things you could try:
31
32- If you're working in a language with mutable data structures and your
33 implementation allows outside code to mutate the school's internal DB
34 directly, see if you can prevent this. Feel free to introduce additional
35 tests.
36
37Then please share your thoughts in a comment on the submission. Did this
38experiment make the code better? Worse? Did you learn anything from it?
39
40## Rust Installation
41
42Refer to the [exercism help page][help-page] for Rust installation and learning
43resources.
44
45## Writing the Code
46
47Execute the tests with:
48
49```bash
50$ cargo test
51```
52
53All but the first test have been ignored. After you get the first test to
54pass, open the tests source file which is located in the `tests` directory
55and remove the `#[ignore]` flag from the next test and get the tests to pass
56again. Each separate test is a function with `#[test]` flag above it.
57Continue, until you pass every test.
58
59If you wish to run all ignored tests without editing the tests source file, use:
60
61```bash
62$ cargo test -- --ignored
63```
64
65To run a specific test, for example `some_test`, you can use:
66
67```bash
68$ cargo test some_test
69```
70
71If the specific test is ignored use:
72
73```bash
74$ cargo test some_test -- --ignored
75```
76
77To learn more about Rust tests refer to the [online test documentation][rust-tests]
78
79Make sure to read the [Modules][modules] chapter if you
80haven't already, it will help you with organizing your files.
81
82## Further improvements
83
84After you have solved the exercise, please consider using the additional utilities, described in the [installation guide](https://exercism.io/tracks/rust/installation), to further refine your final solution.
85
86To format your solution, inside the solution directory use
87
88```bash
89cargo fmt
90```
91
92To see, if your solution contains some common ineffective use cases, inside the solution directory use
93
94```bash
95cargo clippy --all-targets
96```
97
98## Submitting the solution
99
100Generally you should submit all files in which you implemented your solution (`src/lib.rs` in most cases). If you are using any external crates, please consider submitting the `Cargo.toml` file. This will make the review process faster and clearer.
101
102## Feedback, Issues, Pull Requests
103
104The [exercism/rust](https://github.com/exercism/rust) repository on GitHub is the home for all of the Rust exercises. If you have feedback about an exercise, or want to help implement new exercises, head over there and create an issue. Members of the rust track team are happy to help!
105
106If you want to know more about Exercism, take a look at the [contribution guide](https://github.com/exercism/docs/blob/master/contributing-to-language-tracks/README.md).
107
108[help-page]: https://exercism.io/tracks/rust/learning
109[modules]: https://doc.rust-lang.org/book/ch07-02-defining-modules-to-control-scope-and-privacy.html
110[cargo]: https://doc.rust-lang.org/book/ch14-00-more-about-cargo.html
111[rust-tests]: https://doc.rust-lang.org/book/ch11-02-running-tests.html
112
113## Source
114
115A pairing session with Phil Battos at gSchool [http://gschool.it](http://gschool.it)
116
117## Submitting Incomplete Solutions
118It's possible to submit an incomplete solution so you can see how others have completed the exercise.
diff --git a/rust/grade-school/src/lib.rs b/rust/grade-school/src/lib.rs
new file mode 100644
index 0000000..266fb1f
--- /dev/null
+++ b/rust/grade-school/src/lib.rs
@@ -0,0 +1,22 @@
1use std::collections::{BTreeMap, BTreeSet};
2
3#[derive(Default)]
4pub struct School(BTreeMap<u32, BTreeSet<String>>);
5
6impl School {
7 pub fn new() -> School {
8 Self::default()
9 }
10
11 pub fn add(&mut self, grade: u32, student: &str) {
12 self.0.entry(grade).or_default().insert(student.to_string());
13 }
14
15 pub fn grades(&self) -> Vec<u32> {
16 self.0.keys().cloned().collect()
17 }
18
19 pub fn grade(&self, grade: u32) -> Option<Vec<String>> {
20 self.0.get(&grade).map(|vs| vs.iter().cloned().collect())
21 }
22}
diff --git a/rust/grade-school/tests/grade-school.rs b/rust/grade-school/tests/grade-school.rs
new file mode 100644
index 0000000..3f9f060
--- /dev/null
+++ b/rust/grade-school/tests/grade-school.rs
@@ -0,0 +1,75 @@
1use grade_school as school;
2
3fn some_strings(v: &[&str]) -> Option<Vec<String>> {
4 Some(v.iter().map(|s| s.to_string()).collect())
5}
6
7#[test]
8fn test_grades_for_empty_school() {
9 let s = school::School::new();
10 assert_eq!(s.grades(), vec![]);
11}
12
13#[test]
14fn test_grades_for_one_student() {
15 let mut s = school::School::new();
16 s.add(2, "Aimee");
17 assert_eq!(s.grades(), vec![2]);
18}
19
20#[test]
21fn test_grades_for_several_students_are_sorted() {
22 let mut s = school::School::new();
23 s.add(2, "Aimee");
24 s.add(7, "Logan");
25 s.add(4, "Blair");
26 assert_eq!(s.grades(), vec![2, 4, 7]);
27}
28
29#[test]
30fn test_grades_when_several_students_have_the_same_grade() {
31 let mut s = school::School::new();
32 s.add(2, "Aimee");
33 s.add(2, "Logan");
34 s.add(2, "Blair");
35 assert_eq!(s.grades(), vec![2]);
36}
37
38#[test]
39fn test_grade_for_empty_school() {
40 let s = school::School::new();
41 assert_eq!(s.grade(1), None);
42}
43
44#[test]
45fn test_grade_when_no_students_have_that_grade() {
46 let mut s = school::School::new();
47 s.add(7, "Logan");
48 assert_eq!(s.grade(1), None);
49}
50
51#[test]
52fn test_grade_for_one_student() {
53 let mut s = school::School::new();
54 s.add(2, "Aimee");
55 assert_eq!(s.grade(2), some_strings(&["Aimee"]));
56}
57
58#[test]
59fn test_grade_returns_students_sorted_by_name() {
60 let mut s = school::School::new();
61 s.add(2, "James");
62 s.add(2, "Blair");
63 s.add(2, "Paul");
64 assert_eq!(s.grade(2), some_strings(&["Blair", "James", "Paul"]));
65}
66
67#[test]
68fn test_add_students_to_different_grades() {
69 let mut s = school::School::new();
70 s.add(3, "Chelsea");
71 s.add(7, "Logan");
72 assert_eq!(s.grades(), vec![3, 7]);
73 assert_eq!(s.grade(3), some_strings(&["Chelsea"]));
74 assert_eq!(s.grade(7), some_strings(&["Logan"]));
75}