solverforge_core/score/
simple.rs1use std::cmp::Ordering;
4use std::fmt;
5
6use super::traits::{ParseableScore, Score, ScoreParseError};
7use super::ScoreLevel;
8
9#[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
26#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
27pub struct SimpleScore {
28 score: i64,
29}
30
31impl SimpleScore {
32 pub const ZERO: SimpleScore = SimpleScore { score: 0 };
34
35 pub const ONE: SimpleScore = SimpleScore { score: 1 };
37
38 #[inline]
40 pub const fn of(score: i64) -> Self {
41 SimpleScore { score }
42 }
43
44 #[inline]
46 pub const fn score(&self) -> i64 {
47 self.score
48 }
49}
50
51impl Score for SimpleScore {
52 #[inline]
53 fn is_feasible(&self) -> bool {
54 self.score >= 0
55 }
56
57 #[inline]
58 fn zero() -> Self {
59 SimpleScore::ZERO
60 }
61
62 #[inline]
63 fn levels_count() -> usize {
64 1
65 }
66
67 fn to_level_numbers(&self) -> Vec<i64> {
68 vec![self.score]
69 }
70
71 fn from_level_numbers(levels: &[i64]) -> Self {
72 assert_eq!(levels.len(), 1, "SimpleScore requires exactly 1 level");
73 SimpleScore::of(levels[0])
74 }
75
76 impl_score_scale!(SimpleScore { score } => of);
77
78 fn level_label(index: usize) -> ScoreLevel {
79 match index {
80 0 => ScoreLevel::Soft,
81 _ => panic!("SimpleScore has 1 level, got index {}", index),
82 }
83 }
84
85 #[inline]
86 fn to_scalar(&self) -> f64 {
87 self.score as f64
88 }
89}
90
91impl Ord for SimpleScore {
92 fn cmp(&self, other: &Self) -> Ordering {
93 self.score.cmp(&other.score)
94 }
95}
96
97impl_score_ops!(SimpleScore { score } => of);
98
99impl fmt::Debug for SimpleScore {
100 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
101 write!(f, "SimpleScore({})", self.score)
102 }
103}
104
105impl fmt::Display for SimpleScore {
106 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
107 write!(f, "{}", self.score)
108 }
109}
110
111impl ParseableScore for SimpleScore {
113 fn parse(s: &str) -> Result<Self, ScoreParseError> {
114 let s = s.trim();
115 let s = s.strip_suffix("init").unwrap_or(s);
117
118 s.parse::<i64>()
119 .map(SimpleScore::of)
120 .map_err(|e| ScoreParseError {
121 message: format!("Invalid SimpleScore '{}': {}", s, e),
122 })
123 }
124
125 fn to_string_repr(&self) -> String {
126 self.score.to_string()
127 }
128}
129
130impl From<i64> for SimpleScore {
131 fn from(score: i64) -> Self {
132 SimpleScore::of(score)
133 }
134}