#![deny(missing_docs)]
use std::any::{Any, TypeId};
use std::collections::HashMap;
#[cfg(feature = "audit")]
use std::collections::HashSet;
use std::hash::{BuildHasherDefault, Hasher};
#[cfg(feature = "audit")]
use std::path::{Path, PathBuf};
use std::sync::OnceLock;
pub use xuanji::{BoundaryKind, Outcome, Report, Severity, Violation};
pub const RUNTIME_SEAM_RULE: &str = "only declared origins may cross the seam";
pub trait Tracked: Any {
fn as_any(&self) -> &dyn Any;
}
impl<T: Any> Tracked for T {
fn as_any(&self) -> &dyn Any {
self
}
}
#[derive(Default)]
struct FoldHasher(u64);
impl Hasher for FoldHasher {
fn finish(&self) -> u64 {
self.0
}
fn write(&mut self, bytes: &[u8]) {
for &b in bytes {
self.0 = self.0.rotate_left(8) ^ b as u64;
}
}
fn write_u64(&mut self, i: u64) {
self.0 ^= i;
}
fn write_u128(&mut self, i: u128) {
self.0 ^= i as u64 ^ (i >> 64) as u64;
}
}
type TidMap<V> = HashMap<TypeId, V, BuildHasherDefault<FoldHasher>>;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Posture {
Event,
Panic,
}
impl Posture {
pub fn as_str(&self) -> &'static str {
match self {
Posture::Event => "event",
Posture::Panic => "panic",
}
}
}
#[derive(Debug, Clone)]
pub struct RuntimeBoundary {
seam: &'static str,
allowed: Vec<&'static str>,
reason: String,
severity: Severity,
posture: Posture,
}
impl RuntimeBoundary {
pub fn at(seam: &'static str) -> RuntimeSeamDraft {
RuntimeSeamDraft { seam }
}
pub fn seam(&self) -> &str {
self.seam
}
pub fn allowed_origins(&self) -> &[&'static str] {
&self.allowed
}
pub fn reason(&self) -> &str {
&self.reason
}
pub fn severity(&self) -> Severity {
self.severity
}
pub fn posture(&self) -> Posture {
self.posture
}
}
pub struct RuntimeSeamDraft {
seam: &'static str,
}
impl RuntimeSeamDraft {
pub fn only_origins<I>(self, origins: I) -> RuntimeBoundaryDraft
where
I: IntoIterator<Item = &'static str>,
{
RuntimeBoundaryDraft {
seam: self.seam,
allowed: origins.into_iter().collect(),
severity: Severity::Enforce,
posture: Posture::Event,
}
}
}
pub struct RuntimeBoundaryDraft {
seam: &'static str,
allowed: Vec<&'static str>,
severity: Severity,
posture: Posture,
}
impl RuntimeBoundaryDraft {
pub fn warn(mut self) -> Self {
self.severity = Severity::Warn;
self
}
pub fn panic_on_violation(mut self) -> Self {
self.posture = Posture::Panic;
self
}
pub fn because(self, reason: &str) -> RuntimeBoundary {
RuntimeBoundary {
seam: self.seam,
allowed: self.allowed,
reason: reason.to_string(),
severity: self.severity,
posture: self.posture,
}
}
}
#[derive(Debug, Clone)]
pub struct OriginEntry {
type_id: TypeId,
origin: &'static str,
type_name: &'static str,
}
impl OriginEntry {
pub fn new(type_id: TypeId, origin: &'static str, type_name: &'static str) -> Self {
OriginEntry {
type_id,
origin,
type_name,
}
}
}
struct Seam {
allowed: Vec<&'static str>,
reason: String,
severity: Severity,
posture: Posture,
}
struct OriginInfo {
origin: &'static str,
type_name: &'static str,
}
struct Registry {
origins: TidMap<OriginInfo>,
seams: HashMap<&'static str, Seam>,
}
static REGISTRY: OnceLock<Registry> = OnceLock::new();
pub fn install<B, O>(boundaries: B, origins: O)
where
B: IntoIterator<Item = RuntimeBoundary>,
O: IntoIterator<Item = OriginEntry>,
{
let mut seams = HashMap::new();
for b in boundaries {
if seams.contains_key(b.seam) {
panic!(
"louke: runtime seam '{}' declared more than once — each seam is declared exactly \
once (a duplicate would silently shadow the earlier boundary)",
b.seam
);
}
seams.insert(
b.seam,
Seam {
allowed: b.allowed,
reason: b.reason,
severity: b.severity,
posture: b.posture,
},
);
}
let mut origin_map: TidMap<OriginInfo> = TidMap::default();
for e in origins {
if origin_map.contains_key(&e.type_id) {
panic!(
"louke: an origin for type '{}' was registered more than once — each type \
registers its origin exactly once",
e.type_name
);
}
origin_map.insert(
e.type_id,
OriginInfo {
origin: e.origin,
type_name: e.type_name,
},
);
}
if REGISTRY
.set(Registry {
origins: origin_map,
seams,
})
.is_err()
{
panic!("louke: install called twice — the runtime constitution is write-once");
}
}
fn check_crossing(
seam: &str,
type_id: TypeId,
registry: &Registry,
) -> Result<Option<Violation>, String> {
let s = registry.seams.get(seam).ok_or_else(|| {
format!(
"an undeclared seam is never enforced — declare the RuntimeBoundary or fix the \
probe's seam name: probe references undeclared runtime seam '{seam}'"
)
})?;
let info = registry.origins.get(&type_id);
let origin = info.map(|i| i.origin);
let allowed = match origin {
Some(o) => s.allowed.contains(&o),
None => false,
};
if allowed {
return Ok(None);
}
let finding = match info {
Some(i) => format!("{} ({})", i.origin, i.type_name),
None => "<unregistered origin>".to_string(),
};
let rule = format!(
"{RUNTIME_SEAM_RULE} (only origins: {})",
s.allowed.join(", ")
);
Ok(Some(Violation::new(
BoundaryKind::Runtime,
seam.to_string(),
rule,
finding,
s.reason.clone(),
s.severity,
)))
}
#[doc(hidden)]
pub fn __react(seam: &'static str, type_id: TypeId) {
let registry = REGISTRY.get().unwrap_or_else(|| {
panic!("louke: assert_boundary!(\"{seam}\", …) ran before louke::install")
});
match check_crossing(seam, type_id, registry) {
Ok(None) => {}
Ok(Some(violation)) => {
emit(&violation);
let posture = registry
.seams
.get(seam)
.map(|s| s.posture)
.unwrap_or(Posture::Event);
if posture == Posture::Panic && violation.severity == Severity::Enforce {
panic!(
"louke: runtime boundary '{seam}' violated by {}",
violation.finding
);
}
}
Err(message) => panic!("louke constitution error: {message}"),
}
}
#[allow(clippy::type_complexity)]
static SINK: OnceLock<Box<dyn Fn(&Violation) + Send + Sync>> = OnceLock::new();
pub fn set_sink<F>(sink: F)
where
F: Fn(&Violation) + Send + Sync + 'static,
{
if SINK.set(Box::new(sink)).is_err() {
panic!("louke: set_sink called twice — the sink is set once at startup");
}
}
fn emit(violation: &Violation) {
match SINK.get() {
Some(sink) => sink(violation),
None => eprintln!(
"louke: runtime boundary violated\n{}",
xuanji::pretty_json(&violation.to_json())
),
}
}
#[macro_export]
macro_rules! register_origin {
($ty:ty) => {
$crate::OriginEntry::new(
::std::any::TypeId::of::<$ty>(),
::std::module_path!(),
::std::any::type_name::<$ty>(),
)
};
}
#[macro_export]
macro_rules! assert_boundary {
($seam:expr, $obj:expr) => {
$crate::__react($seam, $crate::Tracked::as_any($obj).type_id())
};
}
#[cfg(feature = "audit")]
#[derive(Debug)]
enum Probe {
Literal(String),
Unauditable { file: String },
}
#[cfg(feature = "audit")]
pub fn audit_probe_coverage(declared: &[RuntimeBoundary], src_dirs: &[PathBuf]) -> Outcome {
let mut probes = Vec::new();
for dir in src_dirs {
if let Err(message) = collect_probes(dir, &mut probes) {
return Outcome::ConstitutionError(message);
}
}
let probed_set: HashSet<&str> = probes
.iter()
.filter_map(|p| match p {
Probe::Literal(seam) => Some(seam.as_str()),
Probe::Unauditable { .. } => None,
})
.collect();
let declared_set: HashSet<&str> = declared.iter().map(RuntimeBoundary::seam).collect();
let mut violations = Vec::new();
let mut seen_decl = HashSet::new();
let mut dup_reported = HashSet::new();
for boundary in declared {
let seam = boundary.seam();
if !seen_decl.insert(seam) && dup_reported.insert(seam) {
violations.push(Violation::new(
BoundaryKind::Runtime,
seam.to_string(),
"each runtime seam must be declared exactly once".to_string(),
format!("seam '{seam}' is declared more than once"),
"a duplicate declaration would silently shadow the earlier boundary at install"
.to_string(),
Severity::Enforce,
));
}
}
let mut seen = HashSet::new();
for boundary in declared {
let seam = boundary.seam();
if !probed_set.contains(seam) && seen.insert(seam) {
violations.push(Violation::new(
BoundaryKind::Runtime,
seam.to_string(),
"every declared runtime seam must be probed".to_string(),
format!("declared seam '{seam}' has no assert_boundary! probe"),
"a RuntimeBoundary with no probe is never enforced at runtime".to_string(),
boundary.severity,
));
}
}
let mut seen_probe = HashSet::new();
for probe in &probes {
if let Probe::Literal(seam) = probe {
if !declared_set.contains(seam.as_str()) && seen_probe.insert(seam.as_str()) {
violations.push(Violation::new(
BoundaryKind::Runtime,
seam.clone(),
"every probe must reference a declared seam".to_string(),
format!("probe references undeclared seam '{seam}'"),
"an undeclared seam panics at runtime — declare the RuntimeBoundary or fix the probe's seam name".to_string(),
Severity::Enforce,
));
}
}
}
let mut unauditable_files: Vec<&str> = probes
.iter()
.filter_map(|p| match p {
Probe::Unauditable { file } => Some(file.as_str()),
Probe::Literal(_) => None,
})
.collect();
unauditable_files.sort_unstable();
unauditable_files.dedup();
for file in unauditable_files {
violations.push(
Violation::new(
BoundaryKind::Runtime,
"<un-auditable probe>".to_string(),
"an assert_boundary! seam must be a string literal to be auditable".to_string(),
format!(
"{file} has an assert_boundary! probe with a non-literal seam (const or \
expression), which the CI face cannot trace to a declared seam"
),
"spell the seam as a string literal so probe coverage can be verified".to_string(),
Severity::Enforce,
)
.with_file(Some(file.to_string())),
);
}
if violations.is_empty() {
Outcome::Clean
} else {
Outcome::Violations(Report::new(violations))
}
}
#[cfg(feature = "audit")]
fn collect_probes(dir: &Path, probes: &mut Vec<Probe>) -> Result<(), String> {
let read = std::fs::read_dir(dir).map_err(|e| format!("cannot read {}: {e}", dir.display()))?;
let mut paths = Vec::new();
for entry in read {
let entry =
entry.map_err(|e| format!("cannot read a dir entry under {}: {e}", dir.display()))?;
let file_type = entry
.file_type()
.map_err(|e| format!("cannot stat {}: {e}", entry.path().display()))?;
paths.push((file_type.is_dir(), entry.path()));
}
paths.sort();
for (is_dir, path) in paths {
if is_dir {
collect_probes(&path, probes)?;
} else if path.extension().and_then(|e| e.to_str()) == Some("rs") {
let source = std::fs::read_to_string(&path)
.map_err(|e| format!("cannot read source {}: {e}", path.display()))?;
scan_source(&source, &path.display().to_string(), probes);
}
}
Ok(())
}
#[cfg(feature = "audit")]
fn skip_block_comment(b: &[u8], mut i: usize) -> usize {
let mut depth = 1usize;
i += 2; while i + 1 < b.len() && depth > 0 {
if b[i] == b'/' && b[i + 1] == b'*' {
depth += 1;
i += 2;
} else if b[i] == b'*' && b[i + 1] == b'/' {
depth -= 1;
i += 2;
} else {
i += 1;
}
}
if depth > 0 { b.len() } else { i }
}
#[cfg(feature = "audit")]
fn scan_source(source: &str, file: &str, probes: &mut Vec<Probe>) {
let b = source.as_bytes();
let mut i = 0;
while i < b.len() {
if b[i] == b'/' && i + 1 < b.len() && b[i + 1] == b'/' {
while i < b.len() && b[i] != b'\n' {
i += 1;
}
continue;
}
if b[i] == b'/' && i + 1 < b.len() && b[i + 1] == b'*' {
i = skip_block_comment(b, i);
continue;
}
if let Some(end) = raw_or_byte_string_end(b, i) {
i = end;
continue;
}
if b[i] == b'"' {
i += 1;
while i < b.len() && b[i] != b'"' {
if b[i] == b'\\' {
i += 1;
}
i += 1;
}
i += 1;
continue;
}
if b[i] == b'\'' {
let is_char =
(i + 1 < b.len() && b[i + 1] == b'\\') || (i + 2 < b.len() && b[i + 2] == b'\'');
if is_char {
i += 1;
while i < b.len() && b[i] != b'\'' {
if b[i] == b'\\' {
i += 1;
}
i += 1;
}
i += 1;
continue;
}
}
let left_boundary = i == 0 || !is_ident_byte(b[i - 1]);
if left_boundary {
if let Some(rest) = match_marker(b, i, b"assert_boundary!") {
let (probe, next) = capture_probe(b, rest, file);
if let Some(probe) = probe {
probes.push(probe);
}
i = next;
continue;
}
}
i += 1;
}
}
#[cfg(feature = "audit")]
fn raw_or_byte_string_end(b: &[u8], i: usize) -> Option<usize> {
let mut j = i;
let byte = j < b.len() && b[j] == b'b';
if byte {
j += 1;
}
let raw = j < b.len() && b[j] == b'r';
if raw {
j += 1;
let mut hashes = 0;
while j < b.len() && b[j] == b'#' {
hashes += 1;
j += 1;
}
if j >= b.len() || b[j] != b'"' {
return None;
}
j += 1;
while j < b.len() {
if b[j] == b'"' {
let mut k = j + 1;
let mut h = 0;
while k < b.len() && h < hashes && b[k] == b'#' {
k += 1;
h += 1;
}
if h == hashes {
return Some(k);
}
}
j += 1;
}
return Some(b.len());
}
if byte && j < b.len() && b[j] == b'"' {
j += 1;
while j < b.len() && b[j] != b'"' {
if b[j] == b'\\' {
j += 1;
}
j += 1;
}
return Some((j + 1).min(b.len()));
}
None
}
#[cfg(feature = "audit")]
fn match_marker(b: &[u8], i: usize, marker: &[u8]) -> Option<usize> {
if i + marker.len() <= b.len() && &b[i..i + marker.len()] == marker {
Some(i + marker.len())
} else {
None
}
}
#[cfg(feature = "audit")]
fn is_ident_byte(byte: u8) -> bool {
byte.is_ascii_alphanumeric() || byte == b'_'
}
#[cfg(feature = "audit")]
fn skip_trivia(b: &[u8], mut i: usize) -> usize {
loop {
while i < b.len() && b[i].is_ascii_whitespace() {
i += 1;
}
if b.get(i) == Some(&b'/') && b.get(i + 1) == Some(&b'/') {
while i < b.len() && b[i] != b'\n' {
i += 1;
}
continue;
}
if b.get(i) == Some(&b'/') && b.get(i + 1) == Some(&b'*') {
i = skip_block_comment(b, i);
continue;
}
return i;
}
}
#[cfg(feature = "audit")]
fn capture_probe(b: &[u8], i: usize, file: &str) -> (Option<Probe>, usize) {
let i = skip_trivia(b, i);
if !matches!(b.get(i), Some(&b'(') | Some(&b'{') | Some(&b'[')) {
return (None, i);
}
let i = skip_trivia(b, i + 1);
if i >= b.len() {
return (None, i);
}
if b[i] == b'r' && matches!(b.get(i + 1), Some(b'"') | Some(b'#')) {
if let Some((seam, next)) = raw_string_value(b, i) {
return (Some(Probe::Literal(seam)), next);
}
return (
Some(Probe::Unauditable {
file: file.to_string(),
}),
i,
);
}
if b[i] == b'"' {
let mut j = i + 1;
let start = j;
while j < b.len() && b[j] != b'"' {
if b[j] == b'\\' {
j += 1;
}
j += 1;
}
if j >= b.len() {
return (None, j);
}
let seam = String::from_utf8_lossy(&b[start..j]).into_owned();
return (Some(Probe::Literal(seam)), j + 1);
}
(
Some(Probe::Unauditable {
file: file.to_string(),
}),
i,
)
}
#[cfg(feature = "audit")]
fn raw_string_value(b: &[u8], i: usize) -> Option<(String, usize)> {
let mut j = i + 1; let mut hashes = 0;
while b.get(j) == Some(&b'#') {
hashes += 1;
j += 1;
}
if b.get(j) != Some(&b'"') {
return None;
}
j += 1;
let start = j;
while j < b.len() {
if b[j] == b'"' {
let mut k = j + 1;
let mut h = 0;
while h < hashes && b.get(k) == Some(&b'#') {
k += 1;
h += 1;
}
if h == hashes {
return Some((String::from_utf8_lossy(&b[start..j]).into_owned(), k));
}
}
j += 1;
}
None
}
#[cfg(test)]
mod tests {
use super::*;
fn registry(
seams: &[(&'static str, &[&'static str], Severity)],
origins: &[(TypeId, &'static str, &'static str)],
) -> Registry {
let mut s = HashMap::new();
for (seam, allowed, severity) in seams {
s.insert(
*seam,
Seam {
allowed: allowed.to_vec(),
reason: "r".to_string(),
severity: *severity,
posture: Posture::Event,
},
);
}
let mut o: TidMap<OriginInfo> = TidMap::default();
for (tid, origin, name) in origins {
o.insert(
*tid,
OriginInfo {
origin,
type_name: name,
},
);
}
Registry {
origins: o,
seams: s,
}
}
struct Domain;
struct Infra;
#[test]
fn an_allowed_origin_passes() {
let reg = registry(
&[("seam", &["app::domain"], Severity::Enforce)],
&[(TypeId::of::<Domain>(), "app::domain", "Domain")],
);
assert!(
check_crossing("seam", TypeId::of::<Domain>(), ®)
.unwrap()
.is_none()
);
}
#[test]
fn a_disallowed_origin_reacts() {
let reg = registry(
&[("seam", &["app::domain"], Severity::Enforce)],
&[(TypeId::of::<Infra>(), "app::infra", "Infra")],
);
let v = check_crossing("seam", TypeId::of::<Infra>(), ®)
.unwrap()
.unwrap();
assert_eq!(v.kind, BoundaryKind::Runtime);
assert!(v.finding.contains("app::infra"));
assert!(
v.file.is_none(),
"an origin-assertion violation has no source file"
);
assert!(
v.to_json()["file"].is_null(),
"the prod default-sink JSON carries file: null"
);
}
#[test]
fn an_unknown_origin_reacts_fail_closed() {
let reg = registry(&[("seam", &["app::domain"], Severity::Enforce)], &[]);
let v = check_crossing("seam", TypeId::of::<Infra>(), ®)
.unwrap()
.unwrap();
assert!(v.finding.contains("<unregistered origin>"), "{}", v.finding);
}
#[test]
fn an_undeclared_seam_is_a_constitution_error() {
let reg = registry(&[], &[]);
let err = check_crossing("ghost", TypeId::of::<Domain>(), ®).unwrap_err();
assert!(err.contains("undeclared runtime seam 'ghost'"), "{err}");
}
#[test]
fn the_builder_carries_posture_and_severity() {
let b = RuntimeBoundary::at("s")
.only_origins(["app::domain"])
.panic_on_violation()
.warn()
.because("r");
assert_eq!(b.seam(), "s");
assert_eq!(b.allowed_origins(), &["app::domain"]);
}
#[test]
fn the_fold_hasher_distinguishes_types() {
let mut m: TidMap<u8> = TidMap::default();
m.insert(TypeId::of::<Domain>(), 1);
m.insert(TypeId::of::<Infra>(), 2);
assert_eq!(m.get(&TypeId::of::<Domain>()), Some(&1));
assert_eq!(m.get(&TypeId::of::<Infra>()), Some(&2));
assert_eq!(m.len(), 2);
}
#[cfg(feature = "audit")]
fn boundary(seam: &'static str, severity: Severity) -> RuntimeBoundary {
let draft = RuntimeBoundary::at(seam).only_origins(["o"]);
let draft = if severity == Severity::Warn {
draft.warn()
} else {
draft
};
draft.because("r")
}
#[test]
#[cfg(feature = "audit")]
fn scan_collects_only_literal_probes_skipping_comments_and_strings() {
let src = r#"
fn setup() { louke::install([RuntimeBoundary::at("domain-entry").only_origins(["app::domain"]).because("x")], []); }
fn used() { assert_boundary!("domain-entry", obj); }
// a comment mentioning assert_boundary!("ignored-comment") must not count
let s = "assert_boundary!(\"ignored-string\", x)";
"#;
let mut probes = Vec::new();
scan_source(src, "test.rs", &mut probes);
let literals: Vec<&str> = probes
.iter()
.filter_map(|p| match p {
Probe::Literal(s) => Some(s.as_str()),
Probe::Unauditable { .. } => None,
})
.collect();
assert_eq!(
literals,
vec!["domain-entry"],
"{probes:?} should hold only the real probe"
);
assert!(
!literals.contains(&"ignored-comment") && !literals.contains(&"ignored-string"),
"markers in comments/strings must not count: {literals:?}"
);
assert!(
!probes
.iter()
.any(|p| matches!(p, Probe::Unauditable { .. })),
"no un-auditable probe in this fixture"
);
}
#[test]
#[cfg(feature = "audit")]
fn scan_flags_a_non_literal_seam_probe_as_unauditable() {
let src = r#"
const SEAM: &str = "domain-entry";
fn used() { assert_boundary!(SEAM, obj); }
fn ok() { assert_boundary!("explicit", obj); }
"#;
let mut probes = Vec::new();
scan_source(src, "test.rs", &mut probes);
assert!(
probes
.iter()
.any(|p| matches!(p, Probe::Unauditable { .. })),
"a const-seam probe must be flagged un-auditable: {probes:?}"
);
assert!(
probes
.iter()
.any(|p| matches!(p, Probe::Literal(s) if s == "explicit")),
"the literal probe is still captured: {probes:?}"
);
}
#[test]
#[cfg(feature = "audit")]
fn a_comment_between_bang_and_paren_does_not_drop_the_probe() {
for src in [
"fn f() { assert_boundary! /* x */ (\"c-seam\", o); }",
"fn f() { assert_boundary! // c\n (\"c-seam\", o); }",
] {
let mut probes = Vec::new();
scan_source(src, "test.rs", &mut probes);
assert!(
probes
.iter()
.any(|p| matches!(p, Probe::Literal(s) if s == "c-seam")),
"a comment between ! and ( must not drop the probe: {probes:?}"
);
}
}
#[test]
#[cfg(feature = "audit")]
fn an_identifier_ending_in_the_marker_is_not_a_probe() {
let src = "fn f() { my_assert_boundary!(\"prefixed\", o); xassert_boundary!(\"fp\", o); }";
let mut probes = Vec::new();
scan_source(src, "test.rs", &mut probes);
assert!(
probes.is_empty(),
"an embedded marker must not count as a probe: {probes:?}"
);
}
#[test]
#[cfg(feature = "audit")]
fn a_raw_string_seam_is_an_auditable_literal() {
let src =
"fn f() { assert_boundary!(r#\"raw-seam\"#, o); assert_boundary!(r\"plain-raw\", o); }";
let mut probes = Vec::new();
scan_source(src, "test.rs", &mut probes);
assert!(
probes
.iter()
.any(|p| matches!(p, Probe::Literal(s) if s == "raw-seam")),
"r#\"…\"# seam value must be captured: {probes:?}"
);
assert!(
probes
.iter()
.any(|p| matches!(p, Probe::Literal(s) if s == "plain-raw")),
"r\"…\" seam value must be captured: {probes:?}"
);
assert!(
!probes
.iter()
.any(|p| matches!(p, Probe::Unauditable { .. })),
"a raw-string seam is auditable, not un-auditable: {probes:?}"
);
}
#[test]
#[cfg(feature = "audit")]
fn a_raw_or_byte_string_does_not_desync_the_scanner() {
let src = r####"
let x = r#"he said "hi""#;
fn f() { assert_boundary!("real-seam", o); }
let y = b"assert_boundary!(\"bytestr\", z)";
"####;
let mut probes = Vec::new();
scan_source(src, "test.rs", &mut probes);
let literals: Vec<&str> = probes
.iter()
.filter_map(|p| match p {
Probe::Literal(s) => Some(s.as_str()),
Probe::Unauditable { .. } => None,
})
.collect();
assert!(
literals.contains(&"real-seam"),
"a raw string must not desync and swallow a later probe: {literals:?}"
);
assert!(
!literals.contains(&"bytestr"),
"a marker inside a byte string must not count: {literals:?}"
);
}
#[cfg(feature = "audit")]
fn literal_seams(probes: &[Probe]) -> Vec<String> {
probes
.iter()
.filter_map(|p| match p {
Probe::Literal(s) => Some(s.clone()),
Probe::Unauditable { .. } => None,
})
.collect()
}
#[cfg(feature = "audit")]
#[test]
fn a_probe_inside_a_nested_block_comment_is_not_counted() {
let mut probes = Vec::new();
scan_source(
r#"/* outer /* inner */ assert_boundary!("s", o); */"#,
"t.rs",
&mut probes,
);
assert!(
probes.is_empty(),
"a probe inside a nested block comment must not count: {probes:?}"
);
}
#[cfg(feature = "audit")]
#[test]
fn a_real_probe_after_a_nested_block_comment_is_still_counted() {
let mut probes = Vec::new();
scan_source(
r#"/* a /* b */ c */ assert_boundary!("real", o);"#,
"t.rs",
&mut probes,
);
assert_eq!(
literal_seams(&probes),
["real"],
"a real probe after a closed nested comment must count: {probes:?}"
);
}
#[cfg(feature = "audit")]
#[test]
fn a_brace_or_bracket_delimited_probe_is_captured() {
let mut probes = Vec::new();
scan_source(
"fn f() { assert_boundary!{\"brace\", o}; assert_boundary![\"bracket\", o]; }",
"t.rs",
&mut probes,
);
let mut seams = literal_seams(&probes);
seams.sort_unstable();
assert_eq!(
seams,
["brace", "bracket"],
"brace/bracket-delimited probes must be captured: {probes:?}"
);
}
#[cfg(feature = "audit")]
#[test]
fn audit_reacts_to_a_duplicate_declared_seam() {
let base = std::env::temp_dir().join(format!("louke-audit-dup-{}", std::process::id()));
let _ = std::fs::remove_dir_all(&base);
let dir = write_dir(&base, "m", "fn f() { assert_boundary!(\"twice\", o); }");
let outcome = audit_probe_coverage(
&[
boundary("twice", Severity::Enforce),
boundary("twice", Severity::Enforce),
],
&[dir],
);
let _ = std::fs::remove_dir_all(&base);
match outcome {
Outcome::Violations(report) => assert!(
report
.violations
.iter()
.any(|v| v.target == "twice" && v.finding.contains("declared more than once")),
"a duplicate declared seam must react: {:?}",
report.violations
),
other => panic!("expected a duplicate-seam violation, got {other:?}"),
}
}
#[cfg(feature = "audit")]
#[test]
fn a_nested_comment_between_bang_and_paren_does_not_drop_the_probe() {
let mut probes = Vec::new();
scan_source(
r#"fn f() { assert_boundary! /* a /* b */ c */ ("nested-trivia", o); }"#,
"t.rs",
&mut probes,
);
assert_eq!(
literal_seams(&probes),
["nested-trivia"],
"a probe after a nested comment between ! and ( must be captured: {probes:?}"
);
}
#[cfg(feature = "audit")]
fn write_dir(base: &Path, name: &str, body: &str) -> PathBuf {
let dir = base.join(name);
std::fs::create_dir_all(&dir).unwrap();
std::fs::write(dir.join("a.rs"), body).unwrap();
dir
}
#[test]
#[cfg(feature = "audit")]
fn audit_probe_coverage_reacts_both_directions() {
let base = std::env::temp_dir().join(format!("louke-audit-{}", std::process::id()));
let _ = std::fs::remove_dir_all(&base);
let clean = write_dir(&base, "clean", "fn f() { assert_boundary!(\"s\", o); }");
assert_eq!(
audit_probe_coverage(&[boundary("s", Severity::Enforce)], &[clean]).exit_code(),
0
);
let unprobed = write_dir(&base, "unprobed", "fn f() {}");
assert_eq!(
audit_probe_coverage(&[boundary("orphan", Severity::Enforce)], &[unprobed]).exit_code(),
1
);
let typo = write_dir(&base, "typo", "fn f() { assert_boundary!(\"ghost\", o); }");
assert_eq!(audit_probe_coverage(&[], &[typo]).exit_code(), 1);
let _ = std::fs::remove_dir_all(&base);
}
#[test]
#[cfg(feature = "audit")]
fn a_warn_severity_unprobed_seam_is_advisory_not_a_failure() {
let base = std::env::temp_dir().join(format!("louke-audit-warn-{}", std::process::id()));
let _ = std::fs::remove_dir_all(&base);
let dir = write_dir(&base, "warn", "fn f() {}");
let outcome = audit_probe_coverage(&[boundary("soft", Severity::Warn)], &[dir]);
assert_eq!(outcome.exit_code(), 0, "warn-only is advisory: {outcome:?}");
assert!(
matches!(outcome, Outcome::Violations(_)),
"it still reports the advisory: {outcome:?}"
);
let _ = std::fs::remove_dir_all(&base);
}
#[test]
#[cfg(feature = "audit")]
fn coverage_spans_the_workspace_corpus() {
let base = std::env::temp_dir().join(format!("louke-audit-corpus-{}", std::process::id()));
let _ = std::fs::remove_dir_all(&base);
let decl_only = write_dir(&base, "crate_a", "fn f() {}");
let probe_only = write_dir(
&base,
"crate_b",
"fn g() { assert_boundary!(\"shared\", o); }",
);
let outcome = audit_probe_coverage(
&[boundary("shared", Severity::Enforce)],
&[decl_only, probe_only],
);
assert_eq!(
outcome.exit_code(),
0,
"the corpus is the union of all dirs: {outcome:?}"
);
let _ = std::fs::remove_dir_all(&base);
}
#[test]
#[cfg(feature = "audit")]
fn an_unauditable_probe_reacts() {
let base = std::env::temp_dir().join(format!("louke-audit-unaud-{}", std::process::id()));
let _ = std::fs::remove_dir_all(&base);
let dir = write_dir(
&base,
"unaud",
"const SEAM: &str = \"s\"; fn f() { assert_boundary!(SEAM, o); }",
);
let outcome = audit_probe_coverage(&[boundary("s", Severity::Enforce)], &[dir]);
assert_eq!(
outcome.exit_code(),
1,
"an un-auditable probe must react: {outcome:?}"
);
let violations = match &outcome {
Outcome::Violations(report) => &report.violations,
other => panic!("expected violations, got {other:?}"),
};
let file = violations
.iter()
.find_map(|v| v.file.as_deref())
.expect("the un-auditable-probe violation carries its source file");
assert!(
file.ends_with("a.rs"),
"file names the probe's source: {file}"
);
let _ = std::fs::remove_dir_all(&base);
}
#[test]
#[cfg(feature = "audit")]
fn a_seam_level_runtime_violation_has_no_file() {
let base =
std::env::temp_dir().join(format!("louke-audit-seamnull-{}", std::process::id()));
let _ = std::fs::remove_dir_all(&base);
let dir = write_dir(&base, "unprobed", "fn f() {}");
let outcome = audit_probe_coverage(&[boundary("orphan", Severity::Enforce)], &[dir]);
let violations = match &outcome {
Outcome::Violations(report) => &report.violations,
other => panic!("expected violations, got {other:?}"),
};
assert!(
violations.iter().all(|v| v.file.is_none()),
"a seam-level runtime violation has no source file: {violations:?}"
);
let _ = std::fs::remove_dir_all(&base);
}
}