1
- use std:: {
2
- collections:: HashSet ,
3
- fmt:: { self , Debug } ,
4
- hash:: Hash ,
5
- } ;
1
+ use std:: fmt:: { self , Debug } ;
6
2
7
3
use super :: { Point , Scale } ;
8
- use crate :: repr:: Data ;
9
4
10
5
#[ derive( Clone , Debug , PartialEq ) ]
11
- pub struct Bar < X = Data , Y = Data > {
6
+ pub struct Bar {
12
7
pub label : Option < String > ,
13
- pub point : Point < X , Y > ,
8
+ pub point : Point ,
14
9
}
15
10
16
- impl < X , Y > Bar < X , Y > {
17
- pub fn new ( label : impl Into < String > , point : impl Into < Point < X , Y > > ) -> Self {
11
+ impl Bar {
12
+ pub fn new ( label : impl Into < String > , point : impl Into < Point > ) -> Self {
18
13
Self {
19
14
point : point. into ( ) ,
20
15
label : Some ( label. into ( ) ) ,
21
16
}
22
17
}
23
18
24
- pub fn from_point ( point : impl Into < Point < X , Y > > ) -> Self {
19
+ pub fn from_point ( point : impl Into < Point > ) -> Self {
25
20
Self {
26
21
point : point. into ( ) ,
27
22
label : None ,
@@ -35,36 +30,19 @@ impl<X, Y> Bar<X, Y> {
35
30
}
36
31
37
32
#[ derive( Clone , Debug , PartialEq ) ]
38
- pub struct BarChart < X = Data , Y = Data >
39
- where
40
- X : Clone + Debug ,
41
- Y : Clone + Debug ,
42
- {
43
- pub bars : Vec < Bar < X , Y > > ,
33
+ pub struct BarChart {
34
+ pub bars : Vec < Bar > ,
44
35
pub x_label : Option < String > ,
45
36
pub y_label : Option < String > ,
46
- pub x_scale : Scale < X > ,
47
- pub y_scale : Scale < Y > ,
37
+ pub x_scale : Scale ,
38
+ pub y_scale : Scale ,
48
39
}
49
40
50
41
#[ allow( dead_code) ]
51
- impl < X , Y > BarChart < X , Y >
52
- where
53
- X : Eq + Clone + Hash + PartialOrd + ToString + Debug ,
54
- Y : Eq + Clone + Hash + PartialOrd + ToString + Debug ,
55
- {
56
- pub fn new (
57
- bars : Vec < Bar < X , Y > > ,
58
- x_scale : Scale < X > ,
59
- y_scale : Scale < Y > ,
60
- ) -> Result < Self , BarChartError > {
61
- match & x_scale {
62
- Scale :: List ( scale) => Self :: assert_list_scales_x ( scale, & bars) ?,
63
- } ;
64
-
65
- match & y_scale {
66
- Scale :: List ( scale) => Self :: assert_list_scales_y ( scale, & bars) ?,
67
- } ;
42
+ impl BarChart {
43
+ pub fn new ( bars : Vec < Bar > , x_scale : Scale , y_scale : Scale ) -> Result < Self , BarChartError > {
44
+ Self :: assert_x_scale ( & x_scale, & bars) ?;
45
+ Self :: assert_y_scale ( & y_scale, & bars) ?;
68
46
69
47
Ok ( Self {
70
48
x_scale,
@@ -75,64 +53,24 @@ where
75
53
} )
76
54
}
77
55
78
- fn assert_list_scales_y ( lst : & [ Y ] , bars : & [ Bar < X , Y > ] ) -> Result < ( ) , BarChartError > {
79
- // Duplicate check and removal
80
- let mut lst: Vec < Y > = lst. to_vec ( ) ;
81
- let set: HashSet < Y > = lst. drain ( ..) . collect ( ) ;
82
-
83
- // Check if all points are on scale.
84
- let mut invalid: Option < Y > = None ;
85
- let valid = bars. iter ( ) . fold ( true , |acc, curr| {
86
- if !acc {
87
- return acc;
56
+ fn assert_x_scale ( scale : & Scale , bars : & [ Bar ] ) -> Result < ( ) , BarChartError > {
57
+ for x in bars. iter ( ) . map ( |bar| & bar. point . x ) {
58
+ if !scale. contains ( x) {
59
+ return Err ( BarChartError :: OutOfRange ( "X" . into ( ) , x. to_string ( ) ) ) ;
88
60
}
89
-
90
- if !set. contains ( & curr. point . y ) {
91
- invalid = Some ( curr. point . y . clone ( ) ) ;
92
- false
93
- } else {
94
- true
95
- }
96
- } ) ;
97
-
98
- if valid {
99
- Ok ( ( ) )
100
- } else {
101
- Err ( BarChartError :: OutOfRange (
102
- "Y" . into ( ) ,
103
- invalid. unwrap ( ) . to_string ( ) ,
104
- ) )
105
61
}
106
- }
107
-
108
- fn assert_list_scales_x ( lst : & [ X ] , bars : & [ Bar < X , Y > ] ) -> Result < ( ) , BarChartError > {
109
- // Duplicate check and removal
110
- let mut lst: Vec < X > = lst. to_vec ( ) ;
111
- let set: HashSet < X > = lst. drain ( ..) . collect ( ) ;
112
62
113
- let mut invalid: Option < X > = None ;
114
-
115
- let valid = bars. iter ( ) . fold ( true , |acc, curr| {
116
- if !acc {
117
- return acc;
118
- }
63
+ Ok ( ( ) )
64
+ }
119
65
120
- if !set. contains ( & curr. point . x ) {
121
- invalid = Some ( curr. point . x . clone ( ) ) ;
122
- false
123
- } else {
124
- true
66
+ fn assert_y_scale ( scale : & Scale , bars : & [ Bar ] ) -> Result < ( ) , BarChartError > {
67
+ for y in bars. iter ( ) . map ( |bar| & bar. point . y ) {
68
+ if !scale. contains ( y) {
69
+ return Err ( BarChartError :: OutOfRange ( "Y" . into ( ) , y. to_string ( ) ) ) ;
125
70
}
126
- } ) ;
127
-
128
- if valid {
129
- Ok ( ( ) )
130
- } else {
131
- Err ( BarChartError :: OutOfRange (
132
- "X" . into ( ) ,
133
- invalid. unwrap ( ) . to_string ( ) ,
134
- ) )
135
71
}
72
+
73
+ Ok ( ( ) )
136
74
}
137
75
138
76
pub fn x_label ( mut self , label : impl Into < String > ) -> Self {
@@ -169,49 +107,56 @@ impl std::error::Error for BarChartError {}
169
107
170
108
#[ cfg( test) ]
171
109
mod barchart_tests {
110
+ use super :: super :: ScaleKind ;
172
111
use super :: * ;
112
+ use crate :: repr:: Data ;
173
113
174
- fn create_barchart < ' a > ( ) -> BarChart < usize , & ' a str > {
114
+ fn create_barchart ( ) -> BarChart {
175
115
let p1 = vec ! [ "one" , "two" , "three" , "four" , "five" ] ;
176
116
let p2 = [ 1 , 2 , 3 , 4 , 5 ] ;
177
117
178
118
let bars = p2
179
119
. into_iter ( )
180
120
. zip ( p1. into_iter ( ) )
181
- . map ( |point| Bar :: from_point ( point) )
121
+ . map ( |point| Bar :: from_point ( ( Data :: Integer ( point. 0 ) , Data :: Text ( point . 1 . to_string ( ) ) ) ) )
182
122
. collect ( ) ;
183
123
184
- let x_scale: Scale < usize > = {
124
+ let x_scale = {
185
125
let rng = 0 ..60 ;
186
126
187
- Scale :: List ( rng. collect ( ) )
127
+ Scale :: new ( rng, ScaleKind :: Integer )
128
+ } ;
129
+ let y_scale = {
130
+ let values = vec ! [ "one" , "two" , "three" , "four" , "five" ] ;
131
+
132
+ Scale :: new ( values, ScaleKind :: Text )
188
133
} ;
189
- let y_scale: Scale < & str > = Scale :: List ( vec ! [ "one" , "two" , "three" , "four" , "five" ] ) ;
190
134
191
135
match BarChart :: new ( bars, x_scale, y_scale) {
192
136
Ok ( bar) => bar. x_label ( "Number" ) . y_label ( "Language" ) ,
193
137
Err ( e) => panic ! ( "{}" , e) ,
194
138
}
195
139
}
196
140
197
- fn out_of_range ( ) -> Result < BarChart < isize , isize > , BarChartError > {
141
+ fn out_of_range ( ) -> Result < BarChart , BarChartError > {
198
142
let xs = [ 1 , 5 , 6 , 11 , 15 ] ;
199
143
let ys = [ 4 , 5 , 6 , 7 , 8 ] ;
200
144
201
145
let bars = xs
202
146
. into_iter ( )
203
147
. zip ( ys. into_iter ( ) )
204
- . map ( |point| Bar :: from_point ( point) )
148
+ . map ( |point| Bar :: from_point ( ( Data :: Integer ( point. 0 ) , Data :: Integer ( point . 1 ) ) ) )
205
149
. collect ( ) ;
206
150
207
- let x_scale: Scale < isize > = {
151
+ let x_scale = {
208
152
let rng = -5 ..11 ;
209
153
210
- Scale :: List ( rng. collect ( ) )
154
+ Scale :: new ( rng, ScaleKind :: Integer )
211
155
} ;
212
- let y_scale: Scale < isize > = {
156
+ let y_scale = {
213
157
let rng = 2 ..10 ;
214
- Scale :: List ( rng. collect ( ) )
158
+
159
+ Scale :: new ( rng, ScaleKind :: Integer )
215
160
} ;
216
161
217
162
BarChart :: new ( bars, x_scale, y_scale)
0 commit comments