use super::Problem;
use super::config::RuleConf;
use super::parser::{Stream, Token};
pub mod comments;
pub mod common;
pub mod documents;
pub mod indentation;
pub mod lines;
pub mod quoted_strings;
pub mod scalars;
pub mod spacing;
#[derive(Debug, Clone, Copy)]
pub enum Alt {
AnyBool,
AnyInt,
AnyStr,
Bool(bool),
Str(&'static str),
}
#[derive(Debug, Clone, Copy)]
pub enum OptKind {
Bool,
Int,
OneOf(&'static [Alt]),
ListOf(&'static [Alt]),
}
#[derive(Debug, Clone, Copy)]
pub enum Default {
Bool(bool),
Int(i64),
Str(&'static str),
EmptyList,
StrList(&'static [&'static str]),
}
#[derive(Debug, Clone, Copy)]
pub struct OptSpec {
pub name: &'static str,
pub kind: OptKind,
pub default: Default,
}
pub struct Ctx<'s, 'a> {
pub stream: &'s Stream<'a>,
pub idx: usize,
}
impl<'s, 'a> Ctx<'s, 'a> {
pub fn token(&self) -> &'s Token {
&self.stream.tokens[self.idx]
}
pub fn prev(&self) -> Option<&'s Token> {
self.idx.checked_sub(1).map(|i| &self.stream.tokens[i])
}
pub fn next(&self) -> Option<&'s Token> {
self.stream.tokens.get(self.idx + 1)
}
pub fn nextnext(&self) -> Option<&'s Token> {
self.stream.tokens.get(self.idx + 2)
}
pub const fn buffer(&self) -> &'a str {
self.stream.buffer
}
}
#[derive(Default)]
pub struct States {
pub anchors: documents::AnchorsState,
pub indentation: indentation::State,
pub key_duplicates: documents::KeysState,
pub key_ordering: documents::KeysState,
pub quoted_strings: quoted_strings::State,
pub truthy: scalars::TruthyState,
}
pub type TokenCheck = fn(&RuleConf, &Ctx<'_, '_>, &mut States, &mut Vec<Problem>);
pub type CommentCheck = fn(&RuleConf, &Stream<'_>, usize, &mut Vec<Problem>);
pub type LineCheck = fn(&RuleConf, &Stream<'_>, usize, &mut Vec<Problem>);
#[derive(Clone, Copy)]
pub enum Check {
Token(TokenCheck),
Comment(CommentCheck),
Line(LineCheck),
}
pub struct RuleSpec {
pub id: &'static str,
pub options: &'static [OptSpec],
pub validate: Option<fn(&RuleConf) -> Option<String>>,
pub check: Check,
}
pub static RULES: &[RuleSpec] = &[
documents::ANCHORS,
spacing::BRACES,
spacing::BRACKETS,
spacing::COLONS,
spacing::COMMAS,
comments::COMMENTS,
comments::COMMENTS_INDENTATION,
documents::DOCUMENT_END,
documents::DOCUMENT_START,
lines::EMPTY_LINES,
documents::EMPTY_VALUES,
scalars::FLOAT_VALUES,
spacing::HYPHENS,
indentation::INDENTATION,
documents::KEY_DUPLICATES,
documents::KEY_ORDERING,
lines::LINE_LENGTH,
lines::NEW_LINE_AT_END_OF_FILE,
lines::NEW_LINES,
scalars::OCTAL_VALUES,
quoted_strings::QUOTED_STRINGS,
lines::TRAILING_SPACES,
scalars::TRUTHY,
];
pub fn get(id: &str) -> Option<&'static RuleSpec> {
RULES.iter().find(|spec| spec.id == id)
}