oparlint-suites 0.0.2

Lint suites that can be run by oparlint
Documentation
// SPDX-FileCopyrightText: Politik im Blick developers
// SPDX-FileCopyrightText: Wolfgang Silbermayr <wolfgang@silbermayr.at>
//
// SPDX-License-Identifier: AGPL-3.0-or-later OR EUPL-1.2

use oparlint_linting::{LintSuite, LintingResult};
use oparlint_lints::json::{FieldIsEmailLint, FieldIsStringLint, ObjectContainsFieldLint};
use serde_json::{Map, Value};

use crate::Optionality;

/// A lint suite for verifying the validity of a field containing an E-Mail address.
#[derive(Debug)]
pub struct EmailFieldSuite<'a> {
    field_name: &'a str,
    field_optionality: Optionality,
    fields: &'a Map<String, Value>,
}

impl<'a> EmailFieldSuite<'a> {
    /// Create a new lint suite.
    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(())
    }
}