Polygon Struct

We will create a Polygon struct which contain some points. Copy the code below to https://play.rust-lang.org/ and fill in the missing methods to make the tests pass:

  1. // TODO: remove this when you're done with your implementation.
  2. #![allow(unused_variables, dead_code)]
  3. pub struct Point {
  4. // add fields
  5. }
  6. impl Point {
  7. // add methods
  8. }
  9. pub struct Polygon {
  10. // add fields
  11. }
  12. impl Polygon {
  13. // add methods
  14. }
  15. pub struct Circle {
  16. // add fields
  17. }
  18. impl Circle {
  19. // add methods
  20. }
  21. pub enum Shape {
  22. Polygon(Polygon),
  23. Circle(Circle),
  24. }
  25. #[cfg(test)]
  26. mod tests {
  27. use super::*;
  28. fn round_two_digits(x: f64) -> f64 {
  29. (x * 100.0).round() / 100.0
  30. }
  31. #[test]
  32. fn test_point_magnitude() {
  33. let p1 = Point::new(12, 13);
  34. assert_eq!(round_two_digits(p1.magnitude()), 17.69);
  35. }
  36. #[test]
  37. fn test_point_dist() {
  38. let p1 = Point::new(10, 10);
  39. let p2 = Point::new(14, 13);
  40. assert_eq!(round_two_digits(p1.dist(p2)), 5.00);
  41. }
  42. #[test]
  43. fn test_point_add() {
  44. let p1 = Point::new(16, 16);
  45. let p2 = p1 + Point::new(-4, 3);
  46. assert_eq!(p2, Point::new(12, 19));
  47. }
  48. #[test]
  49. fn test_polygon_left_most_point() {
  50. let p1 = Point::new(12, 13);
  51. let p2 = Point::new(16, 16);
  52. let mut poly = Polygon::new();
  53. poly.add_point(p1);
  54. poly.add_point(p2);
  55. assert_eq!(poly.left_most_point(), Some(p1));
  56. }
  57. #[test]
  58. fn test_polygon_iter() {
  59. let p1 = Point::new(12, 13);
  60. let p2 = Point::new(16, 16);
  61. let mut poly = Polygon::new();
  62. poly.add_point(p1);
  63. poly.add_point(p2);
  64. let points = poly.iter().cloned().collect::<Vec<_>>();
  65. assert_eq!(points, vec![Point::new(12, 13), Point::new(16, 16)]);
  66. }
  67. #[test]
  68. fn test_shape_perimeters() {
  69. let mut poly = Polygon::new();
  70. poly.add_point(Point::new(12, 13));
  71. poly.add_point(Point::new(17, 11));
  72. poly.add_point(Point::new(16, 16));
  73. let shapes = vec![
  74. Shape::from(poly),
  75. Shape::from(Circle::new(Point::new(10, 20), 5)),
  76. ];
  77. let perimeters = shapes
  78. .iter()
  79. .map(Shape::perimeter)
  80. .map(round_two_digits)
  81. .collect::<Vec<_>>();
  82. assert_eq!(perimeters, vec![15.48, 31.42]);
  83. }
  84. }
  85. #[allow(dead_code)]
  86. fn main() {}

Since the method signatures are missing from the problem statements, the key part of the exercise is to specify those correctly. You don’t have to modify the tests.

Other interesting parts of the exercise:

  • Derive a Copy trait for some structs, as in tests the methods sometimes don’t borrow their arguments.
  • Discover that Add trait must be implemented for two objects to be addable via “+”. Note that we do not discuss generics until Day 3.