use oparlint_linting::{LintSuite, LintingResult};
use oparlint_lints::{
entities::common::IdMatchesUrlLint,
json::{FieldIsStringLint, FieldIsUrlLint, ObjectContainsFieldLint},
};
use serde_json::{Map, Value};
use url::Url;
#[derive(Debug)]
pub struct IdFieldSuite<'a> {
fields: &'a Map<String, Value>,
id: &'a Url,
}
impl<'a> IdFieldSuite<'a> {
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(())
}
}