///|
pub(all) enum BackStack {
SameOrder
Reversed
}
///|
pub(all) enum PrintMode {
Automatic
Manual(BackStack)
}
///|
pub(all) enum Collation {
Collated
Uncollated
}
///|
pub(all) struct PrintOptions {
copies : Int32
reverse_sheets : Bool
collation : Collation
mode : PrintMode
}
///|
pub(all) struct Impression {
copy : Int32
sheet : Int32
back : Bool
}
///|
pub(all) struct PrintPass {
reload : Bool
impressions : Array[Impression]
}
///|
pub(all) struct PrintSchedule {
options : PrintOptions
passes : Array[PrintPass]
}
///|
fn validate_print_options(
sheets : Int32,
options : PrintOptions,
) -> Result[Unit, WorkflowError] {
if sheets < 1 || sheets > 25000 || options.copies < 1 || options.copies > 1000 {
return Err(
workflow_error("print", "expected 1..25000 sheets and 1..1000 copies"),
)
}
if sheets * options.copies > 100000 {
return Err(workflow_error("print", "job exceeds 100000 physical sheets"))
}
Ok(())
}
///|
/// Schedule explicit impressions. Manual refeed order is chosen by the caller;
/// it expresses a calibrated stack permutation, not a printer-driver promise.
pub fn schedule_print(
booklet : Booklet,
options : PrintOptions,
) -> Result[PrintSchedule, WorkflowError] {
match recover_booklet(booklet) {
Err(e) => return Err(e)
Ok(_) => ()
}
let count = booklet.sheets.length()
match validate_print_options(count, options) {
Err(e) => return Err(e)
Ok(_) => ()
}
let work : Array[Impression] = []
match options.collation {
Collated =>
for copy in 1..<=options.copies {
for index in 0..
for index in 0.. {
let impressions : Array[Impression] = []
for front in work {
impressions.push(front)
impressions.push({ ..front, back: true, })
}
passes.push({ reload: false, impressions, })
}
Manual(stack) => {
let backs : Array[Impression] = []
for index in 0.. index
Reversed => work.length() - 1 - index
}
backs.push({ ..work[position], back: true, })
}
passes.push({ reload: false, impressions: work, })
passes.push({ reload: true, impressions: backs, })
}
}
Ok({ options, passes, })
}