Skip to main content

lemma/inversion/
target.rs

1//! Target specification for inversion queries
2
3use crate::planning::semantics::LiteralValue;
4use crate::OperationResult;
5use serde::Serialize;
6
7/// Desired outcome for an inversion query
8#[derive(Debug, Clone, PartialEq, Serialize)]
9pub struct Target {
10    /// The comparison operator
11    pub op: TargetOp,
12
13    /// The desired outcome (value or veto)
14    /// None means "any value" (wildcard for non-veto results)
15    pub outcome: Option<OperationResult>,
16}
17
18/// Comparison operators for targets
19#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize)]
20pub enum TargetOp {
21    /// Equal to (=)
22    Eq,
23    /// Not equal to (!=)
24    Neq,
25    /// Less than (<)
26    Lt,
27    /// Less than or equal to (<=)
28    Lte,
29    /// Greater than (>)
30    Gt,
31    /// Greater than or equal to (>=)
32    Gte,
33}
34
35impl Target {
36    /// Create a target for a specific value with equality operator
37    pub fn value(value: LiteralValue) -> Self {
38        Self {
39            op: TargetOp::Eq,
40            outcome: Some(OperationResult::Value(Box::new(value))),
41        }
42    }
43
44    /// Create a target for a specific veto message
45    pub fn veto(message: Option<String>) -> Self {
46        Self {
47            op: TargetOp::Eq,
48            outcome: Some(OperationResult::Veto(message)),
49        }
50    }
51
52    /// Create a target for any veto
53    pub fn any_veto() -> Self {
54        Self::veto(None)
55    }
56
57    /// Create a target for any value (non-veto)
58    pub fn any_value() -> Self {
59        Self {
60            op: TargetOp::Eq,
61            outcome: None,
62        }
63    }
64
65    /// Create a target with a custom operator
66    pub fn with_op(op: TargetOp, outcome: OperationResult) -> Self {
67        Self {
68            op,
69            outcome: Some(outcome),
70        }
71    }
72
73    /// Format target for display
74    pub fn format(&self) -> String {
75        let op_str = match self.op {
76            TargetOp::Eq => "=",
77            TargetOp::Neq => "!=",
78            TargetOp::Lt => "<",
79            TargetOp::Lte => "<=",
80            TargetOp::Gt => ">",
81            TargetOp::Gte => ">=",
82        };
83
84        let value_str = match &self.outcome {
85            None => "any".to_string(),
86            Some(OperationResult::Value(v)) => v.to_string(),
87            Some(OperationResult::Veto(Some(msg))) => format!("veto({})", msg),
88            Some(OperationResult::Veto(None)) => "veto".to_string(),
89        };
90
91        format!("{} {}", op_str, value_str)
92    }
93}