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}