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::{
    entities::common::IdMatchesUrlLint,
    json::{FieldIsStringLint, FieldIsUrlLint, ObjectContainsFieldLint},
};
use serde_json::{Map, Value};
use url::Url;

/// A lint suite for verifying the validity of the `id` field.
#[derive(Debug)]
pub struct IdFieldSuite<'a> {
    fields: &'a Map<String, Value>,
    id: &'a Url,
}

impl<'a> IdFieldSuite<'a> {
    /// Create a new lint suite.
    pub fn new(fields: &'a Map<String, Value>, id: &'a Url) -> Self {
        Self { fields, id }
    }
}

const FIELD_NAME: &str = "id";

#[async_trait::async_trait]
impl<'a> LintSuite for IdFieldSuite<'a> {
    type Output = ();

    fn identifier(&self) -> String {
        format!("{FIELD_NAME}-field")
    }

    fn title(&self) -> String {
        format!("JSON object contains a valid `{FIELD_NAME}` field")
    }

    async fn execute<L: oparlint_linting::Linter + Send>(self, linter: &mut L) -> LintingResult {
        let field_value =
            linter.execute_lint(ObjectContainsFieldLint::new(FIELD_NAME, self.fields))?;
        let field_string_value =
            linter.execute_lint(FieldIsStringLint::new(FIELD_NAME, field_value))?;
        let id = linter.execute_lint(FieldIsUrlLint::new(FIELD_NAME, &field_string_value))?;
        _ = linter.execute_lint(IdMatchesUrlLint::new(self.id, &id));

        Ok(())
    }
}