# Quiz 3

```rust
// This quiz tests:
// - Generics
// - Traits
//
// An imaginary magical school has a new report card generation system written
// in Rust! Currently, the system only supports creating report cards where the
// student's grade is represented numerically (e.g. 1.0 -> 5.5). However, the
// school also issues alphabetical grades (A+ -> F-) and needs to be able to
// print both types of report card!
//
// Make the necessary code changes in the struct `ReportCard` and the impl
// block to support alphabetical report cards in addition to numerical ones.

// TODO: Adjust the struct as described above.
struct ReportCard {
    grade: f32,
    student_name: String,
    student_age: u8,
}

// TODO: Adjust the impl block as described above.
impl ReportCard {
    fn print(&self) -> String {
        format!(
            "{} ({}) - achieved a grade of {}",
            &self.student_name, &self.student_age, &self.grade,
        )
    }
}

fn main() {
    // You can optionally experiment here.
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn generate_numeric_report_card() {
        let report_card = ReportCard {
            grade: 2.1,
            student_name: "Tom Wriggle".to_string(),
            student_age: 12,
        };
        assert_eq!(
            report_card.print(),
            "Tom Wriggle (12) - achieved a grade of 2.1",
        );
    }

    #[test]
    fn generate_alphabetic_report_card() {
        let report_card = ReportCard {
            grade: "A+",
            student_name: "Gary Plotter".to_string(),
            student_age: 11,
        };
        assert_eq!(
            report_card.print(),
            "Gary Plotter (11) - achieved a grade of A+",
        );
    }
}
```

* In this quiz we are tasked to adjust `ReportCard` and its implementation to accept both text grade and float grade.
* We can use generics for this.
* First we need to change the `ReportCard` struct so it will accept generic types for `grade` field like this:

  ```rust
  struct ReportCard<T> {
      grade: T,
      student_name: String,
      student_age: u8,
  }
  ```
* Then we adjust the implementation to accept generics as well like this:

  ```rust
  impl<T> ReportCard<T> {
      fn print(&self) -> String {
          format!(
              "{} ({}) - achieved a grade of {}",
              &self.student_name, &self.student_age, &self.grade,
          )
      }
  }
  ```
* But we still have some error below when compiling.

  ```
  error[E0277]: `T` doesn't implement `std::fmt::Display`
  ```
* This is because `format!` need certain traits.
* So we can add the `std::fmt::Display` trait into our `impl` syntax like this:

  ```rust
  impl<T: std::fmt::Display> ReportCard<T> {
      fn print(&self) -> String {
          format!(
              "{} ({}) - achieved a grade of {}",
              &self.student_name, &self.student_age, &self.grade,
          )
      }
  }
  ```
* In this quiz Rust compiler is very useful, it can suggest what trait should be added in the `impl` syntax.

## References

* [Traits](https://doc.rust-lang.org/book/ch10-02-traits.html)
* [Generic Data Types](https://doc.rust-lang.org/book/ch10-01-syntax.html)
* [Bounds](https://doc.rust-lang.org/rust-by-example/generics/bounds.html)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://bagus-cahyono.gitbook.io/programming-notes/rust/rustlings_exercise/quiz_3.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
