Skip to main content

lemma/inversion/
target.rs

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