solverforge_core/constraint.rs
1//! Core constraint types.
2//!
3//! This module provides fundamental constraint identification and classification
4//! types used throughout the constraint evaluation system.
5
6/// Reference to a constraint for identification.
7///
8/// # Example
9///
10/// ```
11/// use solverforge_core::ConstraintRef;
12///
13/// let cr = ConstraintRef::new("scheduling", "NoOverlap");
14/// assert_eq!(cr.full_name(), "scheduling/NoOverlap");
15///
16/// let simple = ConstraintRef::new("", "Simple");
17/// assert_eq!(simple.full_name(), "Simple");
18/// ```
19#[derive(Debug, Clone, PartialEq, Eq, Hash)]
20pub struct ConstraintRef {
21 /// Package/module containing the constraint.
22 pub package: String,
23 /// Name of the constraint.
24 pub name: String,
25}
26
27impl ConstraintRef {
28 /// Creates a new constraint reference.
29 pub fn new(package: impl Into<String>, name: impl Into<String>) -> Self {
30 Self {
31 package: package.into(),
32 name: name.into(),
33 }
34 }
35
36 /// Returns the fully qualified name.
37 pub fn full_name(&self) -> String {
38 if self.package.is_empty() {
39 self.name.clone()
40 } else {
41 format!("{}/{}", self.package, self.name)
42 }
43 }
44}
45
46/// Type of impact a constraint has on the score.
47///
48/// # Example
49///
50/// ```
51/// use solverforge_core::ImpactType;
52///
53/// let penalty = ImpactType::Penalty;
54/// let reward = ImpactType::Reward;
55///
56/// assert_ne!(penalty, reward);
57/// ```
58#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
59pub enum ImpactType {
60 /// Penalize (subtract from score).
61 Penalty,
62 /// Reward (add to score).
63 Reward,
64}
65
66#[cfg(test)]
67mod tests {
68 use super::*;
69
70 #[test]
71 fn test_constraint_ref_full_name() {
72 let cr = ConstraintRef::new("my.package", "TestConstraint");
73 assert_eq!(cr.full_name(), "my.package/TestConstraint");
74 }
75
76 #[test]
77 fn test_constraint_ref_empty_package() {
78 let cr = ConstraintRef::new("", "Simple");
79 assert_eq!(cr.full_name(), "Simple");
80 }
81
82 #[test]
83 fn test_impact_type() {
84 assert_ne!(ImpactType::Penalty, ImpactType::Reward);
85 }
86}