rulewright 0.1.1

Executable engineering standards for Rust workspaces
Documentation
use crate::{Example, FileCtx, Violation, infra::parse, violation};

#[rustfmt::skip]
const EXAMPLES: &[Example] = &[
    Example {
        label: "hardcoded https URL",
        code: r#"fn f() { let url = "https://api.example.com/v1"; }"#,
        pass: false,
    },
    Example {
        label: "hardcoded http URL",
        code: r#"fn f() { let url = "http://localhost:3000"; }"#,
        pass: false,
    },
    Example {
        label: "no URL",
        code: "fn f() { let x = 42; }",
        pass: true,
    },
    Example {
        label: "URL in doc comment",
        code: "/// See https://docs.rs/foo for details.",
        pass: true,
    },
    Example {
        label: "URL in regular comment",
        code: "// Reference: https://example.com/spec",
        pass: true,
    },
];

crate::line_rule!(
    hardcoded_url,
    "Flag hardcoded URLs in source code (should use config/env).",
    "Hardcoded URLs break when environments change. Use configuration or environment variables for host-specific URLs.",
    Medium,
);

fn check_hardcoded_url(ctx: &FileCtx<'_>) -> Vec<Violation> {
    let mut out = Vec::new();

    for (i, line) in ctx.lines.iter().enumerate() {
        let trimmed = line.trim();

        if parse::is_comment(trimmed) {
            continue;
        }

        if let Some(idx) = parse::find_url(line) {
            let Some(before) = line.get(..idx) else {
                continue;
            };
            let has_open_quote = before.contains('"');

            if has_open_quote {
                out.push(violation(
                    ctx.rel,
                    i + 1,
                    "hardcoded URL in source — use configuration or environment variable instead",
                ));
            }
        }
    }

    out
}

crate::rulewright_test!(check_hardcoded_url, {
    crate::example_tests!(EXAMPLES, check_hardcoded_url);
});