#![allow(missing_docs)]
use super::ParameterValue;
use crate::{Discipline, TemporalPrecision};
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(tag = "kind", rename_all = "camelCase", deny_unknown_fields)]
pub enum Selector {
All,
EntityType {
#[serde(rename = "objectType")]
object_type: String,
#[serde(rename = "includeSubtypes", default = "yes")]
include_subtypes: bool,
},
Property {
#[serde(rename = "propertySet")]
property_set: Option<String>,
property: String,
operator: ComparisonOperator,
value: Option<ParameterValue>,
#[serde(
rename = "caseSensitive",
default = "yes",
skip_serializing_if = "is_true"
)]
case_sensitive: bool,
#[serde(default, skip_serializing_if = "is_false")]
trim: bool,
#[serde(default, skip_serializing_if = "Option::is_none")]
quantifier: Option<Quantifier>,
#[serde(default, skip_serializing_if = "Option::is_none")]
precision: Option<TemporalPrecision>,
},
PropertyPattern {
#[serde(
rename = "propertySetPattern",
default,
skip_serializing_if = "Option::is_none"
)]
property_set_pattern: Option<String>,
#[serde(rename = "propertyPattern")]
property_pattern: String,
matched: Quantifier,
operator: ComparisonOperator,
value: Option<ParameterValue>,
#[serde(
rename = "caseSensitive",
default = "yes",
skip_serializing_if = "is_true"
)]
case_sensitive: bool,
#[serde(default, skip_serializing_if = "is_false")]
trim: bool,
#[serde(default, skip_serializing_if = "Option::is_none")]
quantifier: Option<Quantifier>,
#[serde(default, skip_serializing_if = "Option::is_none")]
precision: Option<TemporalPrecision>,
},
Classification {
system: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
code: Option<String>,
#[serde(
rename = "codePattern",
default,
skip_serializing_if = "Option::is_none"
)]
code_pattern: Option<String>,
#[serde(rename = "includeDescendants", default)]
include_descendants: bool,
},
AllOf {
operands: Vec<Selector>,
},
AnyOf {
operands: Vec<Selector>,
},
Not {
operand: Box<Selector>,
},
Related {
path: Vec<String>,
#[serde(default, skip_serializing_if = "RelatedQuantifier::is_any")]
quantifier: RelatedQuantifier,
selector: Box<Selector>,
},
Discipline {
value: Discipline,
},
Source {
field: SourceField,
operator: ComparisonOperator,
value: Option<ParameterValue>,
#[serde(
rename = "caseSensitive",
default = "yes",
skip_serializing_if = "is_true"
)]
case_sensitive: bool,
#[serde(default, skip_serializing_if = "is_false")]
trim: bool,
#[serde(default, skip_serializing_if = "Option::is_none")]
quantifier: Option<Quantifier>,
},
RuleOutcome {
rule: String,
outcome: RuleOutcomeKind,
},
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum RuleOutcomeKind {
Passed,
Failed,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum SourceField {
FileName,
Application,
Schema,
Project,
Timestamp,
}
impl SourceField {
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Self::FileName => "fileName",
Self::Application => "application",
Self::Schema => "schema",
Self::Project => "project",
Self::Timestamp => "timestamp",
}
}
}
impl Default for Selector {
fn default() -> Self {
Self::All
}
}
impl Selector {
#[must_use]
pub fn property(
property_set: Option<String>,
property: impl Into<String>,
operator: ComparisonOperator,
value: Option<ParameterValue>,
) -> Self {
Self::Property {
property_set,
property: property.into(),
operator,
value,
case_sensitive: true,
trim: false,
quantifier: None,
precision: None,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum Quantifier {
Any,
All,
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum RelatedQuantifier {
#[default]
Any,
All,
None,
}
impl RelatedQuantifier {
#[allow(clippy::trivially_copy_pass_by_ref)]
fn is_any(&self) -> bool {
matches!(self, Self::Any)
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum ComparisonOperator {
Equals,
NotEquals,
LessThan,
LessThanOrEquals,
GreaterThan,
GreaterThanOrEquals,
Matches,
Like,
Contains,
OneOf,
NoneOf,
Exists,
IsEmpty,
IsNotEmpty,
}
const fn yes() -> bool {
true
}
#[allow(clippy::trivially_copy_pass_by_ref)]
const fn is_true(value: &bool) -> bool {
*value
}
#[allow(clippy::trivially_copy_pass_by_ref)]
const fn is_false(value: &bool) -> bool {
!*value
}