use oparlint_linting::{LintSuite, LintingResult};
use oparlint_lints::json::{FieldIsEmailLint, FieldIsStringLint, ObjectContainsFieldLint};
use serde_json::{Map, Value};
use crate::Optionality;
#[derive(Debug)]
pub struct EmailFieldSuite<'a> {
field_name: &'a str,
field_optionality: Optionality,
fields: &'a Map<String, Value>,
}
impl<'a> EmailFieldSuite<'a> {
pub fn new(
field_name: &'a str,
field_optionality: Optionality,
fields: &'a Map<String, Value>,
) -> Self {
Self {
field_name,
field_optionality,
fields,
}
}
}
#[async_trait::async_trait]
impl<'a> LintSuite for EmailFieldSuite<'a> {
type Output = ();
fn identifier(&self) -> String {
format!("{}-field", self.field_name)
}
fn title(&self) -> String {
match self.field_optionality {
Optionality::Required => {
format!("JSON object contains a valid `{}` field", self.field_name)
}
Optionality::Optional => format!(
"JSON object contains no or a valid `{}` field",
self.field_name
),
}
}
async fn execute<L: oparlint_linting::Linter + Send>(self, linter: &mut L) -> LintingResult {
if self.field_optionality.is_optional() && !self.fields.contains_key(self.field_name) {
return Ok(());
}
let field_value =
linter.execute_lint(ObjectContainsFieldLint::new(self.field_name, self.fields))?;
let field_string_value =
linter.execute_lint(FieldIsStringLint::new(self.field_name, field_value))?;
_ = linter.execute_lint(FieldIsEmailLint::new(self.field_name, &field_string_value))?;
Ok(())
}
}