///|
fn same_physical_sheet(a : Impression, b : Impression) -> Bool {
a.copy == b.copy && a.sheet == b.sheet
}
///|
/// Check coverage and actual refeed pairings, including externally edited passes.
pub fn verify_schedule(
booklet : Booklet,
schedule : PrintSchedule,
) -> Result[Unit, WorkflowError] {
match recover_booklet(booklet) {
Err(e) => return Err(e)
Ok(_) => ()
}
let sheets = booklet.sheets.length()
match validate_print_options(sheets, schedule.options) {
Err(e) => return Err(e)
Ok(_) => ()
}
let count = sheets * schedule.options.copies
let expected_passes = match schedule.options.mode {
Automatic => 1
Manual(_) => 2
}
if schedule.passes.length() != expected_passes {
return Err(workflow_error("passes", "wrong pass count for print mode"))
}
let seen = Array::make(count * 2, false)
for pass_index, pass in schedule.passes {
if pass.reload != (pass_index == 1) {
return Err(
workflow_error(
"passes[\{pass_index}].reload",
"unexpected refeed marker",
),
)
}
let length = if expected_passes == 1 { count * 2 } else { count }
if pass.impressions.length() != length {
return Err(
workflow_error("passes[\{pass_index}]", "incorrect impression count"),
)
}
for index, impression in pass.impressions {
let field = "passes[\{pass_index}][\{index}]"
if impression.sheet < 0 ||
impression.sheet >= sheets ||
impression.copy < 1 ||
impression.copy > schedule.options.copies {
return Err(
workflow_error(field, "out-of-range physical sheet reference"),
)
}
let side = if impression.back { 1 } else { 0 }
let key = ((impression.copy - 1) * sheets + impression.sheet) * 2 + side
if seen[key] {
return Err(workflow_error(field, "duplicate sheet face"))
}
seen[key] = true
match schedule.options.mode {
Automatic => {
if impression.back != (index % 2 == 1) {
return Err(
workflow_error(
field, "automatic pass must alternate front and back",
),
)
}
if index % 2 == 1 &&
!same_physical_sheet(impression, pass.impressions[index - 1]) {
return Err(
workflow_error(
field, "automatic duplex faces belong to different sheets",
),
)
}
}
Manual(stack) => {
if impression.back != (pass_index == 1) {
return Err(
workflow_error(field, "manual pass contains the wrong face"),
)
}
if pass_index == 1 {
let front_index = match stack {
SameOrder => index
Reversed => count - 1 - index
}
if !same_physical_sheet(
impression,
schedule.passes[0].impressions[front_index],
) {
return Err(
workflow_error(
field, "back does not match calibrated refeed order",
),
)
}
}
}
}
}
}
for printed in seen {
if !printed {
return Err(workflow_error("passes", "missing sheet face"))
}
}
let fronts = schedule.passes[0].impressions
for position in 0.. (position / sheets + 1, position % sheets)
Uncollated =>
(
position % schedule.options.copies + 1,
position / schedule.options.copies,
)
}
let sheet = if schedule.options.reverse_sheets {
sheets - 1 - ordinal
} else {
ordinal
}
if impression.copy != copy || impression.sheet != sheet {
return Err(
workflow_error(
"passes[0][\{index}]",
"incorrect copy collation or sheet order",
),
)
}
}
Ok(())
}