plotters_unsable/element/
composable.rs1use super::*;
2use crate::drawing::backend::DrawingBackend;
3use std::borrow::Borrow;
4use std::iter::{once, Once};
5use std::marker::PhantomData;
6use std::ops::Add;
7
8pub struct EmptyElement<Coord, DB: DrawingBackend> {
10 coord: Coord,
11 phantom: PhantomData<DB>,
12}
13
14impl<Coord, DB: DrawingBackend> EmptyElement<Coord, DB> {
15 pub fn at(coord: Coord) -> Self {
16 Self {
17 coord,
18 phantom: PhantomData,
19 }
20 }
21}
22
23impl<Coord, Other, DB: DrawingBackend> Add<Other> for EmptyElement<Coord, DB>
24where
25 Other: Drawable<DB>,
26 for<'a> &'a Other: PointCollection<'a, BackendCoord>,
27{
28 type Output = BoxedElement<Coord, DB, Other>;
29 fn add(self, other: Other) -> Self::Output {
30 BoxedElement {
31 offset: self.coord,
32 inner: other,
33 phantom: PhantomData,
34 }
35 }
36}
37
38impl<'a, Coord, DB: DrawingBackend> PointCollection<'a, Coord> for &'a EmptyElement<Coord, DB> {
39 type Borrow = &'a Coord;
40 type IntoIter = Once<&'a Coord>;
41 fn point_iter(self) -> Self::IntoIter {
42 once(&self.coord)
43 }
44}
45
46impl<Coord, DB: DrawingBackend> Drawable<DB> for EmptyElement<Coord, DB> {
47 fn draw<I: Iterator<Item = BackendCoord>>(
48 &self,
49 _pos: I,
50 _backend: &mut DB,
51 ) -> Result<(), DrawingErrorKind<DB::ErrorType>> {
52 Ok(())
53 }
54}
55
56pub struct BoxedElement<Coord, DB: DrawingBackend, A: Drawable<DB>> {
58 inner: A,
59 offset: Coord,
60 phantom: PhantomData<DB>,
61}
62
63impl<'b, Coord, DB: DrawingBackend, A: Drawable<DB>> PointCollection<'b, Coord>
64 for &'b BoxedElement<Coord, DB, A>
65{
66 type Borrow = &'b Coord;
67 type IntoIter = Once<&'b Coord>;
68 fn point_iter(self) -> Self::IntoIter {
69 once(&self.offset)
70 }
71}
72
73impl<Coord, DB: DrawingBackend, A> Drawable<DB> for BoxedElement<Coord, DB, A>
74where
75 for<'a> &'a A: PointCollection<'a, BackendCoord>,
76 A: Drawable<DB>,
77{
78 fn draw<I: Iterator<Item = BackendCoord>>(
79 &self,
80 mut pos: I,
81 backend: &mut DB,
82 ) -> Result<(), DrawingErrorKind<DB::ErrorType>> {
83 if let Some((x0, y0)) = pos.next() {
84 self.inner.draw(
85 self.inner.point_iter().into_iter().map(|p| {
86 let p = p.borrow();
87 (p.0 + x0, p.1 + y0)
88 }),
89 backend,
90 )?;
91 }
92 Ok(())
93 }
94}
95
96impl<Coord, DB: DrawingBackend, My, Yours> Add<Yours> for BoxedElement<Coord, DB, My>
97where
98 My: Drawable<DB>,
99 for<'a> &'a My: PointCollection<'a, BackendCoord>,
100 Yours: Drawable<DB>,
101 for<'a> &'a Yours: PointCollection<'a, BackendCoord>,
102{
103 type Output = ComposedElement<Coord, DB, My, Yours>;
104 fn add(self, yours: Yours) -> Self::Output {
105 ComposedElement {
106 offset: self.offset,
107 first: self.inner,
108 second: yours,
109 phantom: PhantomData,
110 }
111 }
112}
113
114pub struct ComposedElement<Coord, DB: DrawingBackend, A, B>
116where
117 A: Drawable<DB>,
118 B: Drawable<DB>,
119{
120 first: A,
121 second: B,
122 offset: Coord,
123 phantom: PhantomData<DB>,
124}
125
126impl<'b, Coord, DB: DrawingBackend, A, B> PointCollection<'b, Coord>
127 for &'b ComposedElement<Coord, DB, A, B>
128where
129 A: Drawable<DB>,
130 B: Drawable<DB>,
131{
132 type Borrow = &'b Coord;
133 type IntoIter = Once<&'b Coord>;
134 fn point_iter(self) -> Self::IntoIter {
135 once(&self.offset)
136 }
137}
138
139impl<Coord, DB: DrawingBackend, A, B> Drawable<DB> for ComposedElement<Coord, DB, A, B>
140where
141 for<'a> &'a A: PointCollection<'a, BackendCoord>,
142 for<'b> &'b B: PointCollection<'b, BackendCoord>,
143 A: Drawable<DB>,
144 B: Drawable<DB>,
145{
146 fn draw<I: Iterator<Item = BackendCoord>>(
147 &self,
148 mut pos: I,
149 backend: &mut DB,
150 ) -> Result<(), DrawingErrorKind<DB::ErrorType>> {
151 if let Some((x0, y0)) = pos.next() {
152 self.first.draw(
153 self.first.point_iter().into_iter().map(|p| {
154 let p = p.borrow();
155 (p.0 + x0, p.1 + y0)
156 }),
157 backend,
158 )?;
159 self.second.draw(
160 self.second.point_iter().into_iter().map(|p| {
161 let p = p.borrow();
162 (p.0 + x0, p.1 + y0)
163 }),
164 backend,
165 )?;
166 }
167 Ok(())
168 }
169}
170
171impl<Coord, DB: DrawingBackend, A, B, C> Add<C> for ComposedElement<Coord, DB, A, B>
172where
173 A: Drawable<DB>,
174 for<'a> &'a A: PointCollection<'a, BackendCoord>,
175 B: Drawable<DB>,
176 for<'a> &'a B: PointCollection<'a, BackendCoord>,
177 C: Drawable<DB>,
178 for<'a> &'a C: PointCollection<'a, BackendCoord>,
179{
180 type Output = ComposedElement<Coord, DB, A, ComposedElement<BackendCoord, DB, B, C>>;
181 fn add(self, rhs: C) -> Self::Output {
182 ComposedElement {
183 offset: self.offset,
184 first: self.first,
185 second: ComposedElement {
186 offset: (0, 0),
187 first: self.second,
188 second: rhs,
189 phantom: PhantomData,
190 },
191 phantom: PhantomData,
192 }
193 }
194}