| Crates.io | fast-yaml-linter |
| lib.rs | fast-yaml-linter |
| version | 0.5.0 |
| created_at | 2025-12-13 22:08:18.315839+00 |
| updated_at | 2026-01-19 04:02:08.534199+00 |
| description | YAML linter with rich diagnostics |
| homepage | |
| repository | https://github.com/bug-ops/fast-yaml |
| max_upload_size | |
| id | 1983486 |
| size | 410,930 |
YAML linter with rich diagnostics for the fast-yaml ecosystem.
[!NOTE] This crate provides two distinct components: Linter (validates YAML against rules) and Diagnostic Formatters (render diagnostics for display).
Purpose: Validate YAML against configurable rules and generate diagnostics.
Data flow: YAML text → Vec<Diagnostic>
Built-in rules (21 total):
duplicate-key — Detect duplicate keys in mappingsline-length — Enforce maximum line lengthtrailing-whitespace — Detect trailing whitespacePurpose: Convert diagnostics into human-readable or machine-readable formats.
Data flow: Vec<Diagnostic> → Formatted output
Available formatters:
[!TIP] Linter vs Formatter: Linter validates YAML (what's wrong), Formatters display results (how to show it).
lint_value() accepts already-parsed YAML to avoid double parsinguse fast_yaml_linter::{Linter, TextFormatter, Formatter};
let yaml = r#"
name: John
age: 30
name: duplicate # Error: duplicate key
"#;
// Step 1: Create linter with rules
let linter = Linter::with_all_rules();
// Step 2: Run linter (YAML → Vec<Diagnostic>)
let diagnostics = linter.lint(yaml)?;
// Step 3: Format diagnostics (Vec<Diagnostic> → String)
let formatter = TextFormatter::with_color_auto();
let output = formatter.format(&diagnostics, yaml);
// Step 4: Display output
println!("{}", output);
// Output:
// error[duplicate-key]: duplicate key 'name' found
// --> input:4:1
// |
// 4 | name: duplicate
// | ^^^^ duplicate key defined here
# Ok::<(), Box<dyn std::error::Error>>(())
lint_value()use fast_yaml_linter::Linter;
use fast_yaml_core::Parser;
let yaml = "name: test";
// Parse once
let value = Parser::parse_str(yaml)?;
// Lint the pre-parsed value (no re-parsing)
let linter = Linter::with_all_rules();
let diagnostics = linter.lint_value(yaml, &value);
# Ok::<(), Box<dyn std::error::Error>>(())
[!TIP] Use
lint_value()when you already have a parsed document to avoid parsing twice.
[!NOTE] Python bindings are available through the
fastyaml-rspackage on PyPI.
from fast_yaml._core.lint import lint, Linter, LintConfig, TextFormatter, Severity
# Quick lint
diagnostics = lint("key: value\nkey: duplicate")
for diag in diagnostics:
print(f"{diag.severity}: {diag.message}")
print(f" at line {diag.span.start.line}, column {diag.span.start.column}")
# Custom configuration
config = LintConfig(
max_line_length=120,
indent_size=2,
allow_duplicate_keys=False,
)
linter = Linter(config)
diagnostics = linter.lint(yaml_source)
# Format output
formatter = TextFormatter(use_colors=True)
print(formatter.format(diagnostics, yaml_source))
# Access severity levels
Severity.ERROR # Critical errors
Severity.WARNING # Potential issues
Severity.INFO # Informational
Severity.HINT # Suggestions
The linter includes 21+ rules covering syntax, style, and best practices:
Document Structure:
document-start — Enforce --- document start markerdocument-end — Enforce ... document end markernew-line-at-end-of-file — Require newline at EOFKeys and Values:
duplicate-keys — Detect duplicate keys (ERROR)empty-values — Flag empty valueskey-ordering — Enforce alphabetical key orderingFormatting:
line-length — Enforce maximum line lengthindentation — Check consistent indentationtrailing-whitespace — Detect trailing whitespaceempty-lines — Control empty line usagenew-lines — Enforce newline rulesFlow Collections:
braces — Brace spacing in flow mappings {a: 1}brackets — Bracket spacing in flow sequences [1, 2]commas — Comma placement and spacingcolons — Colon spacing after keysValues:
truthy — Detect ambiguous boolean values (yes/no)quoted-strings — Enforce string quoting stylefloat-values — Validate float formattingoctal-values — Detect octal notationComments:
comments — Comment formatting rulescomments-indentation — Comment indentationAnchors & Aliases:
invalid-anchors — Validate anchor/alias usage[!NOTE] All rules are configurable. Disable specific rules via
LintConfig::with_disabled_rule("rule-name").
use fast_yaml_linter::{Linter, LintConfig};
let config = LintConfig::new()
.with_max_line_length(Some(120))
.with_indent_size(4)
.with_disabled_rule("line-length");
let linter = Linter::with_config(config);
from fast_yaml._core.lint import LintConfig, Linter
config = LintConfig(
max_line_length=120,
indent_size=4,
require_document_start=False,
require_document_end=False,
allow_duplicate_keys=False,
disabled_rules={"line-length"},
)
linter = Linter(config)
Each formatter converts Vec<Diagnostic> to a specific format:
use fast_yaml_linter::TextFormatter;
let formatter = TextFormatter::new().with_color(true);
let output = formatter.format(&diagnostics, yaml);
Output:
error[duplicate-key]: duplicate key 'name' found
--> example.yaml:10:5
|
10 | name: value
| ^^^^^ duplicate key defined here
use fast_yaml_linter::JsonFormatter;
let formatter = JsonFormatter::new();
let json = formatter.format(&diagnostics, yaml);
Output:
[
{
"code": "duplicate-key",
"severity": "error",
"message": "duplicate key 'name' found",
"span": {
"start": { "line": 10, "column": 5, "offset": 145 },
"end": { "line": 10, "column": 9, "offset": 149 }
}
}
]
use fast_yaml_linter::SarifFormatter;
let formatter = SarifFormatter::new();
let sarif = formatter.format(&diagnostics, yaml);
// SARIF 2.1.0 compatible output
[!NOTE] JsonFormatter requires the
json-outputfeature. SarifFormatter requiressarif-outputfeature.
| Feature | Description |
|---|---|
default |
No additional features |
json-output |
Enable JSON formatter |
The linter provides rich diagnostic information:
# Python
diagnostic.code # Rule code (e.g., "duplicate-key")
diagnostic.severity # Severity level
diagnostic.message # Error message
diagnostic.span # Location span
diagnostic.span.start # Start location (line, column, offset)
diagnostic.span.end # End location
diagnostic.context # Source context (optional)
diagnostic.suggestions # Fix suggestions (optional)
Licensed under either of:
at your option.