blob: b2bd178ed9896f2cfe8993c7eff3003e3ba317e3 [file] [log] [blame]
use super::{Drawable, PointCollection};
use plotters_backend::{BackendCoord, DrawingBackend, DrawingErrorKind};
use std::borrow::Borrow;
trait DynDrawable<DB: DrawingBackend> {
fn draw_dyn(
&self,
points: &mut dyn Iterator<Item = BackendCoord>,
backend: &mut DB,
parent_dim: (u32, u32),
) -> Result<(), DrawingErrorKind<DB::ErrorType>>;
}
impl<DB: DrawingBackend, T: Drawable<DB>> DynDrawable<DB> for T {
fn draw_dyn(
&self,
points: &mut dyn Iterator<Item = BackendCoord>,
backend: &mut DB,
parent_dim: (u32, u32),
) -> Result<(), DrawingErrorKind<DB::ErrorType>> {
T::draw(self, points, backend, parent_dim)
}
}
/// The container for a dynamically dispatched element
pub struct DynElement<'a, DB, Coord>
where
DB: DrawingBackend,
Coord: Clone,
{
points: Vec<Coord>,
drawable: Box<dyn DynDrawable<DB> + 'a>,
}
impl<'a, 'b: 'a, DB: DrawingBackend, Coord: Clone> PointCollection<'a, Coord>
for &'a DynElement<'b, DB, Coord>
{
type Point = &'a Coord;
type IntoIter = &'a Vec<Coord>;
fn point_iter(self) -> Self::IntoIter {
&self.points
}
}
impl<'a, DB: DrawingBackend, Coord: Clone> Drawable<DB> for DynElement<'a, DB, Coord> {
fn draw<I: Iterator<Item = BackendCoord>>(
&self,
mut pos: I,
backend: &mut DB,
parent_dim: (u32, u32),
) -> Result<(), DrawingErrorKind<DB::ErrorType>> {
self.drawable.draw_dyn(&mut pos, backend, parent_dim)
}
}
/// The trait that makes the conversion from the statically dispatched element
/// to the dynamically dispatched element
pub trait IntoDynElement<'a, DB: DrawingBackend, Coord: Clone>
where
Self: 'a,
{
/// Make the conversion
fn into_dyn(self) -> DynElement<'a, DB, Coord>;
}
impl<'b, T, DB, Coord> IntoDynElement<'b, DB, Coord> for T
where
T: Drawable<DB> + 'b,
for<'a> &'a T: PointCollection<'a, Coord>,
Coord: Clone,
DB: DrawingBackend,
{
fn into_dyn(self) -> DynElement<'b, DB, Coord> {
DynElement {
points: self
.point_iter()
.into_iter()
.map(|x| x.borrow().clone())
.collect(),
drawable: Box::new(self),
}
}
}