1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
use crate::drawable::{DrawType, Drawable};
use crate::drawing::Renderable;
use crate::shapes::CreateDrawable;
use crate::Graphics;
use graphics_shapes::circle::Circle;
use graphics_shapes::ellipse::Ellipse;
use graphics_shapes::line::Line;
use graphics_shapes::polygon::Polygon;
use graphics_shapes::rect::Rect;
use graphics_shapes::triangle::Triangle;

/// Represents one of the shapes from graphics-shapes so they be used in a collection with
/// generic or type issues
#[derive(Debug, Clone)]
pub enum ShapeBox {
    Line(Drawable<Line>),
    Rect(Drawable<Rect>),
    Triangle(Drawable<Triangle>),
    Circle(Drawable<Circle>),
    Ellipse(Drawable<Ellipse>),
    Polygon(Drawable<Polygon>),
}

pub trait FromDrawable<S: Clone> {
    fn from_drawable(drawable: Drawable<S>) -> ShapeBox;
}

pub trait FromShape<S> {
    fn from_shape(shape: S, draw_type: DrawType) -> ShapeBox;
}

macro_rules! from_drawable {
    ($shape: ty, $shape_box: expr) => {
        impl FromDrawable<$shape> for ShapeBox {
            fn from_drawable(drawable: Drawable<$shape>) -> ShapeBox {
                $shape_box(drawable)
            }
        }

        impl FromShape<$shape> for ShapeBox {
            fn from_shape(shape: $shape, draw_type: DrawType) -> ShapeBox {
                $shape_box(Drawable::from_obj(shape, draw_type))
            }
        }
    };
}

from_drawable!(Line, ShapeBox::Line);
from_drawable!(Rect, ShapeBox::Rect);
from_drawable!(Circle, ShapeBox::Circle);
from_drawable!(Ellipse, ShapeBox::Ellipse);
from_drawable!(Triangle, ShapeBox::Triangle);
from_drawable!(Polygon, ShapeBox::Polygon);

impl Renderable<ShapeBox> for ShapeBox {
    fn render(&self, graphics: &mut Graphics) {
        match self {
            ShapeBox::Line(d) => graphics.draw(d),
            ShapeBox::Rect(d) => graphics.draw(d),
            ShapeBox::Triangle(d) => graphics.draw(d),
            ShapeBox::Circle(d) => graphics.draw(d),
            ShapeBox::Ellipse(d) => graphics.draw(d),
            ShapeBox::Polygon(d) => graphics.draw(d),
        }
    }
}