1use radiate_error::RadiateError;
2#[cfg(feature = "serde")]
3use serde::{Deserialize, Serialize};
4use std::fmt::Debug;
5use std::hash::Hash;
6use std::iter::Sum;
7use std::ops::{Add, Div, Index, Mul, Sub};
8use std::sync::Arc;
9
10pub trait Scored {
13 fn score(&self) -> Option<&Score>;
14}
15
16#[derive(Clone, PartialEq, Default)]
25#[repr(transparent)]
26pub struct Score {
27 values: Arc<[f32]>,
28}
29
30impl Score {
31 pub fn from_vec(values: Vec<f32>) -> Self {
32 if values.iter().any(|&v| v.is_nan()) {
33 panic!("Score value cannot be NaN");
34 }
35
36 Score {
37 values: Arc::from(values),
38 }
39 }
40
41 pub fn as_f32(&self) -> f32 {
42 self.values.get(0).cloned().unwrap_or(f32::NAN)
43 }
44
45 pub fn as_i32(&self) -> i32 {
46 self.values[0] as i32
47 }
48
49 pub fn as_string(&self) -> String {
50 self.values[0].to_string()
51 }
52
53 pub fn as_usize(&self) -> usize {
54 self.values[0] as usize
55 }
56
57 pub fn iter(&self) -> impl Iterator<Item = &f32> + '_ {
58 self.values.iter()
59 }
60}
61
62impl AsRef<[f32]> for Score {
63 fn as_ref(&self) -> &[f32] {
64 &self.values
65 }
66}
67
68impl PartialOrd for Score {
69 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
70 self.values.partial_cmp(&other.values)
71 }
72}
73
74impl Debug for Score {
75 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
76 write!(f, "{:?}", self.values)
77 }
78}
79
80impl Hash for Score {
81 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
82 let mut hash: usize = 0;
83
84 for value in self.values.iter() {
85 let value_hash = value.to_bits();
86 hash = hash.wrapping_add(value_hash as usize);
87 }
88
89 hash.hash(state);
90 }
91}
92
93impl Index<usize> for Score {
94 type Output = f32;
95 fn index(&self, index: usize) -> &Self::Output {
96 &self.values[index]
97 }
98}
99
100impl Into<Vec<f32>> for Score {
101 fn into(self) -> Vec<f32> {
102 self.values.to_vec()
103 }
104}
105
106impl From<f32> for Score {
107 fn from(value: f32) -> Self {
108 if value.is_nan() {
109 panic!("Score value cannot be NaN")
110 }
111
112 Score {
113 values: Arc::from(vec![value]),
114 }
115 }
116}
117
118impl TryFrom<i16> for Score {
119 type Error = RadiateError;
120
121 fn try_from(value: i16) -> Result<Self, Self::Error> {
122 Ok(Score {
123 values: Arc::from(vec![value as f32]),
124 })
125 }
126}
127
128impl From<f64> for Score {
129 fn from(value: f64) -> Self {
130 if value.is_nan() {
131 panic!("Score value cannot be NaN")
132 }
133
134 Score {
135 values: Arc::from(vec![value as f32]),
136 }
137 }
138}
139
140impl From<i32> for Score {
141 fn from(value: i32) -> Self {
142 Score {
143 values: Arc::from(vec![value as f32]),
144 }
145 }
146}
147
148impl From<i64> for Score {
149 fn from(value: i64) -> Self {
150 Score {
151 values: Arc::from(vec![value as f32]),
152 }
153 }
154}
155
156impl From<usize> for Score {
157 fn from(value: usize) -> Self {
158 Score {
159 values: Arc::from(vec![value as f32]),
160 }
161 }
162}
163
164impl From<String> for Score {
165 fn from(value: String) -> Self {
166 Score {
167 values: Arc::from(vec![
168 value.parse::<f32>().expect("Failed to parse string to f32"),
169 ]),
170 }
171 }
172}
173
174impl From<&str> for Score {
175 fn from(value: &str) -> Self {
176 Score {
177 values: Arc::from(vec![
178 value.parse::<f32>().expect("Failed to parse string to f32"),
179 ]),
180 }
181 }
182}
183
184impl From<Vec<f32>> for Score {
185 fn from(value: Vec<f32>) -> Self {
186 Score::from_vec(value)
187 }
188}
189
190impl From<Vec<f64>> for Score {
191 fn from(value: Vec<f64>) -> Self {
192 Score::from_vec(value.into_iter().map(|v| v as f32).collect())
193 }
194}
195
196impl From<Vec<i32>> for Score {
197 fn from(value: Vec<i32>) -> Self {
198 Score::from_vec(value.into_iter().map(|v| v as f32).collect())
199 }
200}
201
202impl From<Vec<i64>> for Score {
203 fn from(value: Vec<i64>) -> Self {
204 Score::from_vec(value.into_iter().map(|v| v as f32).collect())
205 }
206}
207
208impl From<Vec<usize>> for Score {
209 fn from(value: Vec<usize>) -> Self {
210 Score::from_vec(value.into_iter().map(|v| v as f32).collect())
211 }
212}
213
214impl From<Vec<String>> for Score {
215 fn from(value: Vec<String>) -> Self {
216 Score::from_vec(
217 value
218 .into_iter()
219 .map(|v| v.parse::<f32>().unwrap())
220 .collect(),
221 )
222 }
223}
224
225impl From<Vec<&str>> for Score {
226 fn from(value: Vec<&str>) -> Self {
227 Score::from_vec(
228 value
229 .into_iter()
230 .map(|v| v.parse::<f32>().unwrap())
231 .collect(),
232 )
233 }
234}
235
236impl Add for Score {
237 type Output = Self;
238
239 fn add(self, other: Self) -> Self {
240 if self.values.is_empty() {
241 return other;
242 }
243
244 let mut values = Vec::with_capacity(self.values.len());
245
246 for i in 0..self.values.len() {
247 values.push(self.values[i] + other.values[i]);
248 }
249
250 Score {
251 values: Arc::from(values),
252 }
253 }
254}
255
256impl Add<f32> for Score {
257 type Output = Self;
258
259 fn add(self, other: f32) -> Self {
260 if self.values.is_empty() {
261 return Score::from(other);
262 }
263
264 let mut values = Vec::with_capacity(self.values.len());
265 for i in 0..self.values.len() {
266 values.push(self.values[i] + other);
267 }
268
269 Score {
270 values: Arc::from(self.values),
271 }
272 }
273}
274
275impl Sub for Score {
276 type Output = Self;
277
278 fn sub(self, other: Self) -> Self {
279 if self.values.is_empty() {
280 return other;
281 }
282
283 let mut values = Vec::with_capacity(self.values.len());
284
285 for i in 0..self.values.len() {
286 values.push(self.values[i] - other.values[i]);
287 }
288
289 Score {
290 values: Arc::from(values),
291 }
292 }
293}
294
295impl Sub<f32> for Score {
296 type Output = Self;
297
298 fn sub(self, other: f32) -> Self {
299 if self.values.is_empty() {
300 return Score::from(-other);
301 }
302
303 let mut values = Vec::with_capacity(self.values.len());
304 for i in 0..self.values.len() {
305 values.push(self.values[i] - other);
306 }
307
308 Score {
309 values: Arc::from(values),
310 }
311 }
312}
313
314impl Mul for Score {
315 type Output = Self;
316
317 fn mul(self, other: Self) -> Self {
318 if self.values.is_empty() {
319 return other;
320 }
321
322 let mut values = Vec::with_capacity(self.values.len());
323 for i in 0..self.values.len() {
324 values.push(self.values[i] * other.values[i]);
325 }
326
327 Score {
328 values: Arc::from(values),
329 }
330 }
331}
332
333impl Mul<f32> for Score {
334 type Output = Self;
335
336 fn mul(self, other: f32) -> Self {
337 if self.values.is_empty() {
338 return Score::from(other);
339 }
340
341 let mut values = Vec::with_capacity(self.values.len());
342 for i in 0..self.values.len() {
343 values.push(self.values[i] * other);
344 }
345
346 Score {
347 values: Arc::from(values),
348 }
349 }
350}
351
352impl Mul<Score> for f32 {
353 type Output = Score;
354
355 fn mul(self, other: Score) -> Score {
356 if other.values.is_empty() {
357 return Score::from(self);
358 }
359
360 let mut values = Vec::with_capacity(other.values.len());
361 for i in 0..other.values.len() {
362 values.push(other.values[i] * self);
363 }
364
365 Score {
366 values: Arc::from(values),
367 }
368 }
369}
370
371impl Div for Score {
372 type Output = Self;
373
374 fn div(self, other: Self) -> Self {
375 if self.values.is_empty() {
376 return other;
377 }
378
379 let mut values = Vec::with_capacity(self.values.len());
380 for i in 0..self.values.len() {
381 values.push(self.values[i] / other.values[i]);
382 }
383
384 Score {
385 values: Arc::from(values),
386 }
387 }
388}
389
390impl Div<f32> for Score {
391 type Output = Self;
392
393 fn div(self, other: f32) -> Self {
394 if self.values.is_empty() {
395 return Score::from(other);
396 }
397
398 let mut values = Vec::with_capacity(self.values.len());
399 for i in 0..self.values.len() {
400 values.push(self.values[i] / other);
401 }
402
403 Score {
404 values: Arc::from(values),
405 }
406 }
407}
408
409impl Sum for Score {
410 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
411 let mut values = vec![];
412
413 for score in iter {
414 for (i, value) in score.values.iter().enumerate() {
415 if values.len() <= i {
416 values.push(*value);
417 } else {
418 values[i] += value;
419 }
420 }
421 }
422
423 Score {
424 values: Arc::from(values),
425 }
426 }
427}
428
429impl<'a> Sum<&'a Score> for Score {
430 fn sum<I: Iterator<Item = &'a Score>>(iter: I) -> Self {
431 let mut values = vec![];
432
433 for score in iter {
434 for (i, value) in score.values.iter().enumerate() {
435 if values.len() <= i {
436 values.push(*value);
437 } else {
438 values[i] += value;
439 }
440 }
441 }
442
443 Score {
444 values: Arc::from(values),
445 }
446 }
447}
448
449#[cfg(feature = "serde")]
450impl Serialize for Score {
451 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
452 where
453 S: serde::Serializer,
454 {
455 self.values.as_ref().serialize(serializer)
456 }
457}
458
459#[cfg(feature = "serde")]
460impl<'de> Deserialize<'de> for Score {
461 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
462 where
463 D: serde::Deserializer<'de>,
464 {
465 let vec = Vec::<f32>::deserialize(deserializer)?;
466 for value in &vec {
467 if value.is_nan() {
468 return Err(serde::de::Error::custom("Score value cannot be NaN"));
469 }
470 }
471
472 Ok(Score {
473 values: Arc::from(vec),
474 })
475 }
476}
477
478#[cfg(test)]
479mod tests {
480 use super::*;
481
482 #[test]
483 fn test_score_from_vec() {
484 let score = Score::from(vec![1.0, 2.0, 3.0]);
485 assert_eq!(score.values.len(), 3);
486 }
487
488 #[test]
489 fn test_score_from_usize() {
490 let score = Score::from(3);
491 assert_eq!(score.values.len(), 1);
492 assert_eq!(score.as_f32(), 3.0);
493 assert_eq!(score.as_i32(), 3);
494 }
495
496 #[test]
497 fn test_score_from_f32() {
498 let score = Score::from(1.0);
499 assert_eq!(score.as_f32(), 1.0);
500 assert_eq!(score.as_i32(), 1)
501 }
502
503 #[test]
504 fn test_score_from_i32() {
505 let score = Score::from(-5);
506 assert_eq!(score.as_f32(), -5.0);
507 assert_eq!(score.as_i32(), -5);
508 }
509
510 #[test]
511 fn test_score_add() {
512 let score1 = Score::from(vec![1.0, 2.0, 3.0]);
513 let score2 = Score::from(vec![4.0, 5.0, 6.0]);
514 let score3 = score1 + score2;
515
516 assert_eq!(score3.values.len(), 3);
517 assert_eq!(score3.as_f32(), 5.0);
518 assert_eq!(score3[0], 5.0);
519 assert_eq!(score3[1], 7.0);
520 assert_eq!(score3[2], 9.0);
521 }
522
523 #[test]
524 fn test_score_sub() {
525 let score1 = Score::from(vec![5.0, 7.0, 9.0]);
526 let score2 = Score::from(vec![4.0, 5.0, 6.0]);
527 let score3 = score1 - score2;
528 assert_eq!(score3.values.len(), 3);
529 assert_eq!(score3.as_f32(), 1.0);
530 assert_eq!(score3[0], 1.0);
531 assert_eq!(score3[1], 2.0);
532 assert_eq!(score3[2], 3.0);
533 }
534
535 #[test]
536 fn test_score_mul() {
537 let score1 = Score::from(vec![1.0, 2.0, 3.0]);
538 let score2 = Score::from(vec![4.0, 5.0, 6.0]);
539 let score3 = score1 * score2;
540 assert_eq!(score3.values.len(), 3);
541 assert_eq!(score3.as_f32(), 4.0);
542 assert_eq!(score3[0], 4.0);
543 assert_eq!(score3[1], 10.0);
544 assert_eq!(score3[2], 18.0);
545 }
546
547 #[test]
548 fn test_score_div() {
549 let score1 = Score::from(vec![4.0, 8.0, 12.0]);
550 let score2 = Score::from(vec![2.0, 4.0, 6.0]);
551 let score3 = score1 / score2;
552 assert_eq!(score3.values.len(), 3);
553 assert_eq!(score3.as_f32(), 2.0);
554 assert_eq!(score3[0], 2.0);
555 assert_eq!(score3[1], 2.0);
556 assert_eq!(score3[2], 2.0);
557 }
558
559 #[test]
560 #[cfg(feature = "serde")]
561 fn test_score_can_serialize() {
562 let score = Score::from(vec![1.0, 2.0, 3.0]);
563 let serialized = serde_json::to_string(&score).expect("Failed to serialize Score");
564 let deserialized: Score =
565 serde_json::from_str(&serialized).expect("Failed to deserialize Score");
566 assert_eq!(score, deserialized);
567 }
568}