Hone logo
Hone
Problems

Advanced Pattern Matching in Rust

Rust's match expression is a powerful tool for control flow, enabling sophisticated pattern matching that goes beyond simple equality checks. This challenge will test your ability to leverage match with various pattern types, including destructuring, guards, and the use of the _ wildcard. Mastering these techniques is crucial for writing idiomatic and robust Rust code.

Problem Description

You are tasked with creating a function that processes a complex data structure representing different types of geometric shapes and their properties. The function should use Rust's match expression to perform specific actions based on the type and attributes of the shape.

Requirements:

  1. Define an Enum: Create an enum called Shape that can represent:

    • Point with x and y integer coordinates.
    • Circle with a center (which is a Point) and a radius (a float).
    • Rectangle with a top_left (a Point) and width and height (both floats).
    • Triangle with three Point vertices.
  2. Implement a process_shape Function: Create a public function process_shape that takes a Shape enum variant as input and returns a String describing the shape and its properties.

  3. Use match for Pattern Matching: Within process_shape, use a match expression to handle each Shape variant.

  4. Destructuring: For Point, Circle, and Rectangle, destructure the constituent parts (coordinates, center, radius, dimensions) to access their values within the match arms.

  5. Wildcard (_): When processing a Triangle, you don't need to inspect the individual coordinates of its vertices. Use the _ wildcard to ignore them.

  6. Pattern Guards (Optional but encouraged): For Circle and Rectangle, add a pattern guard to check for specific conditions:

    • If a Circle has a radius less than or equal to 0, treat it as an invalid circle.
    • If a Rectangle has a width or height less than or equal to 0, treat it as an invalid rectangle.
    • For valid circles and rectangles, include their dimensions in the output string.
  7. Output Formatting: The output string should be descriptive and clearly indicate the type of shape and its relevant properties.

Expected Behavior:

The process_shape function should correctly identify each Shape variant and format its output string based on the matched pattern and any applied guards.

Edge Cases:

  • Invalid Circle (radius <= 0).
  • Invalid Rectangle (width <= 0 or height <= 0).
  • Handling of Point and Triangle without specific numeric guards.

Examples

Example 1:

Input: Shape::Point { x: 10, y: 20 }
Output: "This is a Point at (10, 20)."
Explanation: The `Point` variant is matched, and its `x` and `y` coordinates are extracted and used in the output string.

Example 2:

Input: Shape::Circle { center: Shape::Point { x: 5, y: 5 }, radius: 7.5 }
Output: "This is a Circle centered at (5, 5) with radius 7.5."
Explanation: The `Circle` variant is matched. The nested `Point` is destructured, and the `radius` is used in the output.

Example 3:

Input: Shape::Rectangle { top_left: Shape::Point { x: 0, y: 10 }, width: 5.0, height: 8.0 }
Output: "This is a Rectangle with top-left corner at (0, 10), width 5.0, and height 8.0."
Explanation: The `Rectangle` variant is matched, destructuring its properties and including them in the output.

Example 4:

Input: Shape::Triangle { p1: Shape::Point { x: 1, y: 2 }, p2: Shape::Point { x: 3, y: 4 }, p3: Shape::Point { x: 5, y: 6 } }
Output: "This is a Triangle."
Explanation: The `Triangle` variant is matched. The `_` wildcard is used to ignore the individual point data.

Example 5 (with guards):

Input: Shape::Circle { center: Shape::Point { x: 0, y: 0 }, radius: -2.0 }
Output: "Invalid Circle: radius cannot be negative."
Explanation: The `Circle` pattern is matched, but the guard `radius <= 0.0` is true, so the alternative output is produced.

Example 6 (with guards):

Input: Shape::Rectangle { top_left: Shape::Point { x: 1, y: 1 }, width: 0.0, height: 10.0 }
Output: "Invalid Rectangle: width and height must be positive."
Explanation: The `Rectangle` pattern is matched, but the guard `width <= 0.0` is true, triggering the invalid rectangle message.

Constraints

  • Integer coordinates for Point will be within the range of i32.
  • Float values for radius, width, and height will be standard f64.
  • The process_shape function must be efficient, with its time complexity for any given shape being constant, O(1), due to direct pattern matching.

Notes

  • Consider how to define the Point struct or enum within your solution. It can be an inner enum variant or a separate struct used within the Shape enum. For this challenge, let's define Point as a separate struct.
  • The use of pattern guards is an excellent way to add conditional logic directly within match arms, making your code cleaner.
  • Think about how to handle the nested Point structure within Circle and Rectangle.
Loading editor...
rust