use crate::path::Path;
use super::config::Config;
#[derive(Debug)]
pub struct FileCtx<'a> {
pub rel: &'a str,
pub path: &'a Path,
pub package_name: Option<&'a str>,
pub package_publishable: Option<bool>,
pub lines: &'a [&'a str],
pub contents: &'a str,
pub config: &'a Config,
}
#[derive(Debug, serde::Serialize)]
pub struct Violation {
pub rel: String,
pub line: usize,
#[serde(skip_serializing_if = "Option::is_none")]
pub column: Option<usize>,
pub message: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub rule: Option<&'static str>,
#[serde(skip)]
pub(crate) fixable: bool,
}
impl Violation {
pub(crate) fn with_rule(mut self, rule: &'static str) -> Self {
self.rule = Some(rule);
self
}
pub(crate) fn with_column(mut self, column: usize) -> Self {
self.column = Some(column);
self
}
pub(crate) fn mark_fixable(&mut self) {
self.fixable = true;
}
#[must_use]
pub const fn is_fixable(&self) -> bool {
self.fixable
}
#[must_use]
pub fn rule_name(&self) -> &str {
self.rule.unwrap_or("unknown")
}
}
pub fn violation(rel: &str, line: usize, msg: impl Into<String>) -> Violation {
Violation {
rel: rel.to_string(),
line,
column: None,
message: msg.into(),
rule: None,
fixable: false,
}
}
impl FileCtx<'_> {
#[must_use]
pub const fn is_explicitly_non_publishable(&self) -> bool {
matches!(self.package_publishable, Some(false))
}
#[must_use]
pub fn line(&self, lineno: usize) -> Option<&str> {
self.lines.get(lineno.checked_sub(1)?).copied()
}
}