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)]

4. pub struct Point {
5. // add fields
6. }

8. impl Point {
9. // add methods
10. }

12. pub struct Polygon {
13. // add fields
14. }

16. impl Polygon {
17. // add methods
18. }

20. pub struct Circle {
21. // add fields
22. }

24. impl Circle {
25. // add methods
26. }

28. pub enum Shape {
29. Polygon(Polygon),
30. Circle(Circle),
31. }

33. #[cfg(test)]
34. mod tests {
35. use super::*;

37. fn round_two_digits(x: f64) -> f64 {
38. (x * 100.0).round() / 100.0
39. }

41. #[test]
42. fn test_point_magnitude() {
43. let p1 = Point::new(12, 13);
44. assert_eq!(round_two_digits(p1.magnitude()), 17.69);
45. }

47. #[test]
48. fn test_point_dist() {
49. let p1 = Point::new(10, 10);
50. let p2 = Point::new(14, 13);
51. assert_eq!(round_two_digits(p1.dist(p2)), 5.00);
52. }

54. #[test]
55. fn test_point_add() {
56. let p1 = Point::new(16, 16);
57. let p2 = p1 + Point::new(-4, 3);
58. assert_eq!(p2, Point::new(12, 19));
59. }

61. #[test]
62. fn test_polygon_left_most_point() {
63. let p1 = Point::new(12, 13);
64. let p2 = Point::new(16, 16);

66. let mut poly = Polygon::new();
67. poly.add_point(p1);
68. poly.add_point(p2);
69. assert_eq!(poly.left_most_point(), Some(p1));
70. }

72. #[test]
73. fn test_polygon_iter() {
74. let p1 = Point::new(12, 13);
75. let p2 = Point::new(16, 16);

77. let mut poly = Polygon::new();
78. poly.add_point(p1);
79. poly.add_point(p2);

81. let points = poly.iter().cloned().collect::<Vec<_>>();
82. assert_eq!(points, vec![Point::new(12, 13), Point::new(16, 16)]);
83. }

85. #[test]
86. fn test_shape_perimeters() {
87. let mut poly = Polygon::new();
88. poly.add_point(Point::new(12, 13));
89. poly.add_point(Point::new(17, 11));
90. poly.add_point(Point::new(16, 16));
91. let shapes = vec![
92. Shape::from(poly),
93. Shape::from(Circle::new(Point::new(10, 20), 5)),
94. ];
95. let perimeters = shapes
96. .iter()
97. .map(Shape::perimeter)
98. .map(round_two_digits)
99. .collect::<Vec<_>>();
100. assert_eq!(perimeters, vec![15.48, 31.42]);
101. }
102. }

104. #[allow(dead_code)]
105. 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.