plotters/element/
dynelem.rs

1use super::{Drawable, PointCollection};
2use plotters_backend::{BackendCoord, DrawingBackend, DrawingErrorKind};
3
4use std::borrow::Borrow;
5
6trait DynDrawable<DB: DrawingBackend> {
7    fn draw_dyn(
8        &self,
9        points: &mut dyn Iterator<Item = BackendCoord>,
10        backend: &mut DB,
11        parent_dim: (u32, u32),
12    ) -> Result<(), DrawingErrorKind<DB::ErrorType>>;
13}
14
15impl<DB: DrawingBackend, T: Drawable<DB>> DynDrawable<DB> for T {
16    fn draw_dyn(
17        &self,
18        points: &mut dyn Iterator<Item = BackendCoord>,
19        backend: &mut DB,
20        parent_dim: (u32, u32),
21    ) -> Result<(), DrawingErrorKind<DB::ErrorType>> {
22        T::draw(self, points, backend, parent_dim)
23    }
24}
25
26/// The container for a dynamically dispatched element
27pub struct DynElement<'a, DB, Coord>
28where
29    DB: DrawingBackend,
30    Coord: Clone,
31{
32    points: Vec<Coord>,
33    drawable: Box<dyn DynDrawable<DB> + 'a>,
34}
35
36impl<'a, 'b: 'a, DB: DrawingBackend, Coord: Clone> PointCollection<'a, Coord>
37    for &'a DynElement<'b, DB, Coord>
38{
39    type Point = &'a Coord;
40    type IntoIter = &'a Vec<Coord>;
41    fn point_iter(self) -> Self::IntoIter {
42        &self.points
43    }
44}
45
46impl<'a, DB: DrawingBackend, Coord: Clone> Drawable<DB> for DynElement<'a, DB, Coord> {
47    fn draw<I: Iterator<Item = BackendCoord>>(
48        &self,
49        mut pos: I,
50        backend: &mut DB,
51        parent_dim: (u32, u32),
52    ) -> Result<(), DrawingErrorKind<DB::ErrorType>> {
53        self.drawable.draw_dyn(&mut pos, backend, parent_dim)
54    }
55}
56
57/// The trait that makes the conversion from the statically dispatched element
58/// to the dynamically dispatched element
59pub trait IntoDynElement<'a, DB: DrawingBackend, Coord: Clone>
60where
61    Self: 'a,
62{
63    /// Make the conversion
64    fn into_dyn(self) -> DynElement<'a, DB, Coord>;
65}
66
67impl<'b, T, DB, Coord> IntoDynElement<'b, DB, Coord> for T
68where
69    T: Drawable<DB> + 'b,
70    for<'a> &'a T: PointCollection<'a, Coord>,
71    Coord: Clone,
72    DB: DrawingBackend,
73{
74    fn into_dyn(self) -> DynElement<'b, DB, Coord> {
75        DynElement {
76            points: self
77                .point_iter()
78                .into_iter()
79                .map(|x| x.borrow().clone())
80                .collect(),
81            drawable: Box::new(self),
82        }
83    }
84}