use super::{
LinkOccurrenceRef, NavigationEvent, NavigationScanOptions, ReferenceScanLimits,
ReferenceScanReport, ReferenceWorkBudget,
};
use crate::{ContentBlockStep as Step, Document, EntryOwnerLocationRef};
use std::ops::ControlFlow;
pub fn scan_references<'ir>(
document: &'ir Document,
limits: ReferenceScanLimits,
mut visit: impl for<'path> FnMut(LinkOccurrenceRef<'ir, 'path>) -> ControlFlow<()>,
) -> ReferenceScanReport {
scan_reference_scope(
document,
ReferenceScope::Document,
limits,
|occurrence, _| visit(occurrence),
)
}
#[derive(Debug, Clone, Copy)]
pub enum ReferenceScope<'a> {
Document,
Overview,
Section(&'a [u32]),
Block {
sections: &'a [u32],
blocks: &'a [Step],
},
Owner(EntryOwnerLocationRef<'a>),
}
pub fn scan_reference_scope<'ir>(
document: &'ir Document,
scope: ReferenceScope<'_>,
limits: ReferenceScanLimits,
mut visit: impl for<'path> FnMut(
LinkOccurrenceRef<'ir, 'path>,
&mut ReferenceWorkBudget,
) -> ControlFlow<()>,
) -> ReferenceScanReport {
scan_navigation_scope(
document,
scope,
limits,
NavigationScanOptions::default(),
|event, budget| {
if let NavigationEvent::Link(occurrence) = event {
visit(occurrence, budget)
} else {
ControlFlow::Continue(())
}
},
)
}
pub fn scan_navigation_scope<'ir>(
document: &'ir Document,
scope: ReferenceScope<'_>,
limits: ReferenceScanLimits,
options: NavigationScanOptions,
visit: impl for<'path> FnMut(
NavigationEvent<'ir, 'path>,
&mut ReferenceWorkBudget,
) -> ControlFlow<()>,
) -> ReferenceScanReport {
let mut budget = ReferenceWorkBudget::new(limits);
scan_navigation_scope_with_budget(document, scope, &mut budget, options, visit)
}
pub fn scan_navigation_scope_with_budget<'ir>(
document: &'ir Document,
scope: ReferenceScope<'_>,
budget: &mut ReferenceWorkBudget,
options: NavigationScanOptions,
visit: impl for<'path> FnMut(
NavigationEvent<'ir, 'path>,
&mut ReferenceWorkBudget,
) -> ControlFlow<()>,
) -> ReferenceScanReport {
super::walker::scan(document, scope, budget, options, visit)
}
pub fn scan_section_references<'ir>(
document: &'ir Document,
sections: &[u32],
limits: ReferenceScanLimits,
mut visit: impl for<'path> FnMut(LinkOccurrenceRef<'ir, 'path>) -> ControlFlow<()>,
) -> ReferenceScanReport {
scan_reference_scope(
document,
ReferenceScope::Section(sections),
limits,
|occurrence, _| visit(occurrence),
)
}
pub fn scan_block_references<'ir>(
document: &'ir Document,
sections: &[u32],
blocks: &[Step],
limits: ReferenceScanLimits,
mut visit: impl for<'path> FnMut(LinkOccurrenceRef<'ir, 'path>) -> ControlFlow<()>,
) -> ReferenceScanReport {
scan_reference_scope(
document,
ReferenceScope::Block { sections, blocks },
limits,
|occurrence, _| visit(occurrence),
)
}
pub fn scan_owner_references<'ir>(
document: &'ir Document,
owner: EntryOwnerLocationRef<'_>,
limits: ReferenceScanLimits,
mut visit: impl for<'path> FnMut(LinkOccurrenceRef<'ir, 'path>) -> ControlFlow<()>,
) -> ReferenceScanReport {
scan_reference_scope(
document,
ReferenceScope::Owner(owner),
limits,
|occurrence, _| visit(occurrence),
)
}