1 use super::{Drawable, PointCollection}; 2 use plotters_backend::{BackendCoord, DrawingBackend, DrawingErrorKind}; 3 4 use std::borrow::Borrow; 5 6 trait DynDrawable<DB: DrawingBackend> { draw_dyn( &self, points: &mut dyn Iterator<Item = BackendCoord>, backend: &mut DB, parent_dim: (u32, u32), ) -> Result<(), DrawingErrorKind<DB::ErrorType>>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 15 impl<DB: DrawingBackend, T: Drawable<DB>> DynDrawable<DB> for T { draw_dyn( &self, points: &mut dyn Iterator<Item = BackendCoord>, backend: &mut DB, parent_dim: (u32, u32), ) -> Result<(), DrawingErrorKind<DB::ErrorType>>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 27 pub struct DynElement<'a, DB, Coord> 28 where 29 DB: DrawingBackend, 30 Coord: Clone, 31 { 32 points: Vec<Coord>, 33 drawable: Box<dyn DynDrawable<DB> + 'a>, 34 } 35 36 impl<'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>; point_iter(self) -> Self::IntoIter41 fn point_iter(self) -> Self::IntoIter { 42 &self.points 43 } 44 } 45 46 impl<'a, DB: DrawingBackend, Coord: Clone> Drawable<DB> for DynElement<'a, DB, Coord> { draw<I: Iterator<Item = BackendCoord>>( &self, mut pos: I, backend: &mut DB, parent_dim: (u32, u32), ) -> Result<(), DrawingErrorKind<DB::ErrorType>>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 59 pub trait IntoDynElement<'a, DB: DrawingBackend, Coord: Clone> 60 where 61 Self: 'a, 62 { 63 /// Make the conversion into_dyn(self) -> DynElement<'a, DB, Coord>64 fn into_dyn(self) -> DynElement<'a, DB, Coord>; 65 } 66 67 impl<'b, T, DB, Coord> IntoDynElement<'b, DB, Coord> for T 68 where 69 T: Drawable<DB> + 'b, 70 for<'a> &'a T: PointCollection<'a, Coord>, 71 Coord: Clone, 72 DB: DrawingBackend, 73 { into_dyn(self) -> DynElement<'b, DB, Coord>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 } 85