moon-ipp

    MoonBit-native IPP codec, capability validation and network printing client

    ipp
    printing
    protocol
    cups
    client
    Download zip
    Author
    Version
    0.1.1
    License
    Apache-2.0
    Last updated
    10 hours ago
    Downloads
    5

    Dependencies

    #moon-ipp

    CI

    MoonBit 原生 IPP 网络打印协议库和客户端。业务系统可以查询打印机能力、预检参数、提交已有文档、查看或取消任务。核心独立于 CUPS,后者仅作为独立互操作测试端。

    模块 liyun6666/moon-ipp · 仓库 moon-ipp · 作者马昀昀 · Apache-2.0。

    #安装

    需要 MoonBit stable 2026-09-18 或更新的兼容版本。网络客户端依赖 moonbitlang/async@0.22.4;native 构建需要 C 编译器,Windows 异步库要求 MSVC。Linux CI 验证 native,JS 客户端通过 Node.js 测试。

    moon add liyun6666/moon-ipp@0.1.1

    在 moon.pkg 中导入所需包:

    import {
    "liyun6666/moon-ipp" @ipp,
    "liyun6666/moon-ipp/client",
    }

    协议核心和参数解析支持 wasm-gc、JS、native;异步客户端支持 JS、native;文件操作 CLI 支持 native。浏览器使用受目标服务 CORS 策略约束。CLI 可从源码运行:

    git clone https://github.com/liyun6666/moon-ipp.git cd moon-ipp moon update moon run cmd/main --target native -- help

    #库 API

    离线创建、编码和解码一份请求:

    let context = @ipp.RequestContext::new("ipp://localhost:8631/ipp/print", user="demo")
    let request = context.printer_attributes(1, requested=["printer-name", "document-format-supported"])
    let wire = @ipp.encode(request)
    let parsed = @ipp.decode(wire)
    assert_eq(parsed, request)

    异步提交已有 PDF,默认先读取能力并调用 Validate-Job:

    let transport = @client.HttpTransport::new()
    let client = @client.Client::new("ipp://localhost:8631/ipp/print", transport)
    let options = @ipp.JobOptions::{
    ..@ipp.JobOptions::new("Monthly report", "application/pdf"),
    sides: Some(@ipp.TwoSidedLongEdge),
    }
    let job = client.print_job(options, pdf_bytes)
    let observations = client.wait_job(job.id)

    代码需要可抛错的函数环境;网络示例需要 async 函数和已有 pdf_bytes。完整离线示例:

    moon run examples/packet --target wasm-gc

    #三个可运行场景

    先准备独立虚拟设备(Ubuntu/Debian):

    sudo apt-get install cups-ipp-utils avahi-daemon sudo systemctl start avahi-daemon mkdir -p /tmp/moon-ipp-spool ippeveprinter -n localhost -p 8631 -2 -s 60 \ -f application/pdf,text/plain -d /tmp/moon-ipp-spool -k "Moon IPP Demo"

    1. 业务报表打印。 查询能力,提交仓库内的有效单页 PDF,取得任务 ID 后等待结束。设备须声明支持 PDF 及所选参数。

    moon run cmd/main --target native -- capabilities --uri ipp://localhost:8631/ipp/print moon run cmd/main --target native -- print --uri ipp://localhost:8631/ipp/print \ --input examples/report.pdf --name "Monthly report" --sides two-sided-long-edge # 用上一步输出的 id 替换 1。 moon run cmd/main --target native -- wait --uri ipp://localhost:8631/ipp/print --job-id 1

    2. 办公室队列管理。 查询设备状态与队列,创建等待文档的任务,再取消它。

    moon run cmd/main --target native -- health --uri ipp://localhost:8631/ipp/print moon run cmd/main --target native -- jobs --uri ipp://localhost:8631/ipp/print --which all moon run cmd/main --target native -- create --uri ipp://localhost:8631/ipp/print --format text/plain --name "Cancel me" # 用 create 输出的 id 替换 2。 moon run cmd/main --target native -- cancel --uri ipp://localhost:8631/ipp/print --job-id 2 moon run cmd/main --target native -- job --uri ipp://localhost:8631/ipp/print --job-id 2

    3. 应用团队的打印集成验收。 自动启动独立 CUPS,完成 PDF 打印、拒绝不支持的格式、取消任务、Create-Job/Send-Document、队列查询及离线 JSON 往返;对比 CUPS 保留的文档字节,并用其 ipptool 交叉验证类型。先停止占用 8631 端口的手动演示设备。

    python3 scripts/interop_cups.py

    证据存于 interop-output/,包括服务端日志、每条命令的输入输出和 result.json,CI 上传证据 artifact。虚拟设备验证协议交互与文档接收;纸面输出需按实体设备另行验证。

    #功能与边界

    • IPP 1.1/2.x 消息、属性组、多值、嵌套集合、常用标准值类型、未知值与二进制文档;默认上限为头部 1 MiB、文档 16 MiB、属性 4096 个、值 16384 个、集合深度 16。
    • 八个操作:Get-Printer-Attributes、Validate-Job、Print-Job、Create-Job、Send-Document、Get-Jobs、Get-Job-Attributes、Cancel-Job。
    • 份数、纸张、单双面、颜色、分辨率、质量、方向、number-up、页范围和文档格式预检;缺失能力通常警告,明确不支持则报错。
    • media-col 尺寸、四边页边距、纸盒及纸张类型;设备健康、队列摘要、能力差异和打印计划预览。
    • 有界 HTTP/HTTPS 传输、请求 ID 关联、超时和取消;同一 Client 只允许一个并发请求。Transport 可注入业务已有网络层。
    • 带类型标签的 JSON 保留集合、未知值和字节;CLI encode、decode、compare 可离线排查。

    文档由上游生成,须是设备支持的格式。首版不提供文档转换、渲染器、USB 驱动、DNS-SD 自动发现、通知订阅或完整 IPP Everywhere 认证,不声称覆盖全部厂商扩展。HTTP 401/403 等明确报错;认证使用调用方设置的 MOON_IPP_AUTHORIZATION 环境变量并要求 ipps://,TLS 使用系统信任根。不要把秘密写进 URI 或日志。

    提交中丢失响应,或成功响应缺少可用任务编号,会抛出 SubmissionUncertain:设备可能已接收文档,应查询队列并核对,客户端不会自动重发。任务查询还会核对返回的 job-id,防止把其他任务的完成状态当作本次结果。终态为 completed、canceled、aborted;超出轮询次数报错。PrintPlan 是参数与状态预览,不保证传输成功。

    #验证与维护

    moon check --target wasm-gc --deny-warn moon test --target wasm-gc --deny-warn moon test --target js --deny-warn moon check --deny-warn moon test --deny-warn moon build --deny-warn moon info moon fmt --check python3 scripts/count_source.py --minimum 4001

    计数只含手写 .mbt 非空非注释实现行,排除测试、生成接口、依赖、构建文件及 Python 测试脚本。测试覆盖字节往返、截断、非法结构、集合预算、日期、URI、参数、任务状态和失败路径。详见 验收记录、AI 辅助申报草稿(须参赛者人工撰写终稿) 和 查重记录。

    原创实现依据 RFC 8010 和 RFC 8011。OpenPrinting CUPS 源码未被复制。依赖与许可证见 第三方说明。

    IppError

    pub(all) suberror IppError {
    Invalid(String)
    Truncated(Int, Int)
    Limit(String)
    Protocol(String)
    Unsupported(String)
    } derive(
    Debug
    )

    IppError::to_repr

    Attribute

    pub(all) struct Attribute {
    name : String
    values : Array[IppValue]
    } derive(Eq,
    Debug
    )

    Attribute::equal

    fn Attribute::equal(Attribute, Attribute) -> Bool

    Attribute::first

    fn Attribute::first(self : Attribute) -> IppValue?

    Attribute::integers

    fn Attribute::integers(name : String, values : Array[Int]) -> Attribute

    Attribute::keywords

    fn Attribute::keywords(name : String, values : Array[String]) -> Attribute

    Attribute::new

    fn Attribute::new(name : String, value : IppValue) -> Attribute

    Attribute::not_equal

    fn Attribute::not_equal(x : Attribute, y : Attribute) -> Bool

    Attribute::string_values

    fn Attribute::string_values(self : Attribute) -> Array[String]

    Attribute::to_json

    fn Attribute::to_json(self : Attribute) -> Json

    Capabilities

    pub(all) struct Capabilities {
    printer : Group
    } derive(Eq,
    Debug
    )

    Capabilities::accepting_jobs

    fn Capabilities::accepting_jobs(self : Capabilities) -> Bool?

    Capabilities::choose_format

    fn Capabilities::choose_format(self : Capabilities, candidates : Array[String]) -> String raise IppError

    Select only an explicitly advertised input format. No conversion is implied.

    Capabilities::default_options

    fn Capabilities::default_options(self : Capabilities, name : String, format : String) -> JobOptions raise IppError

    Capabilities::document_formats

    fn Capabilities::document_formats(self : Capabilities) -> Array[String]

    Capabilities::equal

    Capabilities::from_response

    fn Capabilities::from_response(response : Message) -> Capabilities raise IppError

    Capabilities::health

    Capabilities::integers

    fn Capabilities::integers(self : Capabilities, name : String) -> Array[Int]

    Capabilities::media

    fn Capabilities::media(self : Capabilities) -> Array[String]

    Capabilities::media_database

    fn Capabilities::media_database(self : Capabilities) -> Array[MediaSpec] raise IppError

    Capabilities::name

    fn Capabilities::name(self : Capabilities) -> String

    Capabilities::not_equal

    fn Capabilities::not_equal(x : Capabilities, y : Capabilities) -> Bool

    Capabilities::plan

    fn Capabilities::plan(self : Capabilities, options : JobOptions, document_bytes : Int) -> PrintPlan raise IppError

    Capabilities::require_options

    fn Capabilities::require_options(self : Capabilities, options : JobOptions, document_bytes? : Int) -> Unit raise IppError

    Capabilities::resolutions

    fn Capabilities::resolutions(self : Capabilities) -> Array[Resolution]

    Capabilities::strings

    fn Capabilities::strings(self : Capabilities, name : String) -> Array[String]

    Capabilities::summary_json

    fn Capabilities::summary_json(self : Capabilities) -> Json

    Capabilities::supports_operation

    fn Capabilities::supports_operation(self : Capabilities, operation : Operation) -> Bool?

    Capabilities::validate_media

    fn Capabilities::validate_media(self : Capabilities, spec : MediaSpec) -> Array[Diagnostic] raise IppError

    Capabilities::validate_options

    fn Capabilities::validate_options(self : Capabilities, options : JobOptions, document_bytes? : Int) -> Array[Diagnostic] raise IppError

    CapabilityChange

    pub(all) struct CapabilityChange {
    attribute : String
    kind : ChangeKind
    before : Array[IppValue]
    after : Array[IppValue]
    transient : Bool
    } derive(Eq,
    Debug
    )

    CapabilityChange::equal

    CapabilityChange::not_equal

    fn CapabilityChange::not_equal(x : CapabilityChange, y : CapabilityChange) -> Bool

    CapabilityChange::to_json

    fn CapabilityChange::to_json(self : CapabilityChange) -> Json

    ChangeKind

    pub(all) enum ChangeKind {
    Added
    Removed
    Changed
    } derive(Eq,
    Debug
    )

    ChangeKind::equal

    fn ChangeKind::equal(ChangeKind, ChangeKind) -> Bool

    ChangeKind::not_equal

    fn ChangeKind::not_equal(x : ChangeKind, y : ChangeKind) -> Bool

    DecodeLimits

    pub(all) struct DecodeLimits {
    max_message_bytes : Int
    max_attributes : Int
    max_values : Int
    max_collection_depth : Int
    max_document_bytes : Int
    } derive(Eq,
    Debug
    )

    DecodeLimits::defaults

    fn DecodeLimits::defaults() -> DecodeLimits

    DecodeLimits::equal

    DecodeLimits::not_equal

    fn DecodeLimits::not_equal(x : DecodeLimits, y : DecodeLimits) -> Bool

    DecodeLimits::validate

    fn DecodeLimits::validate(self : DecodeLimits) -> Unit raise IppError

    Diagnostic

    pub(all) struct Diagnostic {
    severity : Severity
    attribute : String
    message : String
    } derive(Eq,
    Debug
    )

    Diagnostic::equal

    fn Diagnostic::equal(Diagnostic, Diagnostic) -> Bool

    Diagnostic::not_equal

    fn Diagnostic::not_equal(x : Diagnostic, y : Diagnostic) -> Bool

    Diagnostic::to_json

    fn Diagnostic::to_json(self : Diagnostic) -> Json

    Group

    pub(all) struct Group {
    tag : Int
    attributes : Array[Attribute]
    } derive(Eq,
    Debug
    )

    Group::equal

    fn Group::equal(Group, Group) -> Bool

    Group::find

    fn Group::find(self : Group, name : String) -> Attribute?

    Group::get_bool

    fn Group::get_bool(self : Group, name : String) -> Bool?

    Group::get_int

    fn Group::get_int(self : Group, name : String) -> Int?

    Group::get_string

    fn Group::get_string(self : Group, name : String) -> String?

    Group::job

    fn Group::job(attributes : Array[Attribute]) -> Group

    Group::not_equal

    fn Group::not_equal(x : Group, y : Group) -> Bool

    Group::operation

    fn Group::operation(attributes : Array[Attribute]) -> Group

    Group::printer

    fn Group::printer(attributes : Array[Attribute]) -> Group

    Group::to_json

    fn Group::to_json(self : Group) -> Json

    Group::to_repr

    IppDateTime

    pub(all) struct IppDateTime {
    year : Int
    month : Int
    day : Int
    hour : Int
    minute : Int
    second : Int
    decisecond : Int
    utc_direction : Int
    utc_hours : Int
    utc_minutes : Int
    } derive(Eq,
    Debug
    )

    IppDateTime::equal

    fn IppDateTime::equal(IppDateTime, IppDateTime) -> Bool

    IppDateTime::not_equal

    fn IppDateTime::not_equal(x : IppDateTime, y : IppDateTime) -> Bool

    IppDateTime::validate

    fn IppDateTime::validate(self : IppDateTime) -> Unit raise IppError

    IppValue

    pub(all) enum IppValue {
    Integer(Int)
    Enumeration(Int)
    Boolean(Bool)
    Range(Int, Int)
    ResolutionValue(Resolution)
    DateTime(IppDateTime)
    Text(String)
    Name(String)
    Keyword(String)
    Uri(String)
    UriScheme(String)
    Charset(String)
    Language(String)
    MimeType(String)
    Octets(Bytes)
    TextWithLanguage(String, String)
    NameWithLanguage(String, String)
    Collection(Array[Attribute])
    OutOfBand(Int)
    Unknown(Int, Bytes)
    } derive(Eq,
    Debug
    )

    IppValue::as_bool

    fn IppValue::as_bool(self : IppValue) -> Bool?

    IppValue::as_int

    fn IppValue::as_int(self : IppValue) -> Int?

    IppValue::as_string

    fn IppValue::as_string(self : IppValue) -> String?

    IppValue::equal

    fn IppValue::equal(IppValue, IppValue) -> Bool

    IppValue::not_equal

    fn IppValue::not_equal(x : IppValue, y : IppValue) -> Bool

    IppValue::tag

    fn IppValue::tag(self : IppValue) -> Int

    IppValue::to_json

    fn IppValue::to_json(self : IppValue) -> Json

    IppValue::to_repr

    Job

    pub(all) struct Job {
    id : Int
    uri : String?
    name : String?
    state : JobState?
    reasons : Array[String]
    message : String?
    impressions_completed : Int?
    attributes : Group
    } derive(Eq,
    Debug
    )

    Job::equal

    fn Job::equal(Job, Job) -> Bool

    Job::from_group

    fn Job::from_group(group : Group) -> Job raise IppError

    Job::not_equal

    fn Job::not_equal(x : Job, y : Job) -> Bool

    Job::to_json

    fn Job::to_json(self : Job) -> Json

    Job::to_repr

    JobObservation

    pub(all) struct JobObservation {
    job : Job
    elapsed_ms : Int
    } derive(Eq,
    Debug
    )

    JobObservation::equal

    JobObservation::not_equal

    fn JobObservation::not_equal(x : JobObservation, y : JobObservation) -> Bool

    JobOptions

    pub(all) struct JobOptions {
    name : String
    document_format : String
    copies : Int
    media : String?
    sides : Sides?
    color_mode : String?
    resolution : Resolution?
    print_quality : Int?
    orientation : Int?
    number_up : Int?
    page_ranges : Array[PageRange]
    } derive(Eq,
    Debug
    )

    JobOptions::attributes

    fn JobOptions::attributes(self : JobOptions) -> Array[Attribute]

    JobOptions::equal

    fn JobOptions::equal(JobOptions, JobOptions) -> Bool

    JobOptions::new

    fn JobOptions::new(name : String, document_format : String) -> JobOptions

    JobOptions::not_equal

    fn JobOptions::not_equal(x : JobOptions, y : JobOptions) -> Bool

    JobOptions::to_json

    fn JobOptions::to_json(self : JobOptions) -> Json

    JobOptions::validate

    fn JobOptions::validate(self : JobOptions) -> Unit raise IppError

    JobState

    pub(all) enum JobState {
    Pending
    PendingHeld
    Processing
    ProcessingStopped
    Canceled
    Aborted
    Completed
    Other(Int)
    } derive(Eq,
    Debug
    )

    JobState::code

    fn JobState::code(self : JobState) -> Int

    JobState::equal

    fn JobState::equal(JobState, JobState) -> Bool

    JobState::name

    fn JobState::name(self : JobState) -> String

    JobState::not_equal

    fn JobState::not_equal(x : JobState, y : JobState) -> Bool

    JobState::terminal

    fn JobState::terminal(self : JobState) -> Bool

    JobState::to_repr

    MediaMargins

    pub(all) struct MediaMargins {
    top : Int
    bottom : Int
    left : Int
    right : Int
    } derive(Eq,
    Debug
    )

    MediaMargins::equal

    MediaMargins::new

    fn MediaMargins::new(top : Int, bottom : Int, left : Int, right : Int) -> MediaMargins raise IppError

    MediaMargins::not_equal

    fn MediaMargins::not_equal(x : MediaMargins, y : MediaMargins) -> Bool

    MediaSize

    pub(all) struct MediaSize {
    x : Int
    y : Int
    } derive(Eq,
    Debug
    )

    MediaSize::a4

    fn MediaSize::a4() -> MediaSize

    MediaSize::collection

    fn MediaSize::collection(self : MediaSize) -> IppValue

    MediaSize::equal

    fn MediaSize::equal(MediaSize, MediaSize) -> Bool

    MediaSize::letter

    fn MediaSize::letter() -> MediaSize

    MediaSize::new

    fn MediaSize::new(x : Int, y : Int) -> MediaSize raise IppError

    Dimensions are expressed in hundredths of a millimetre, as specified by PWG.

    MediaSize::not_equal

    fn MediaSize::not_equal(x : MediaSize, y : MediaSize) -> Bool

    MediaSpec

    pub(all) struct MediaSpec {
    size : MediaSize
    margins : MediaMargins?
    source : String?
    kind : String?
    name : String?
    } derive(Eq,
    Debug
    )

    MediaSpec::collection

    fn MediaSpec::collection(self : MediaSpec) -> IppValue raise IppError

    MediaSpec::equal

    fn MediaSpec::equal(MediaSpec, MediaSpec) -> Bool

    MediaSpec::new

    fn MediaSpec::new(size : MediaSize) -> MediaSpec

    MediaSpec::not_equal

    fn MediaSpec::not_equal(x : MediaSpec, y : MediaSpec) -> Bool

    MediaSpec::validate

    fn MediaSpec::validate(self : MediaSpec) -> Unit raise IppError

    Message

    pub(all) struct Message {
    version : Version
    code : Int
    request_id : Int
    groups : Array[Group]
    document : Bytes
    } derive(Eq,
    Debug
    )

    Message::equal

    fn Message::equal(Message, Message) -> Bool

    Message::find

    fn Message::find(self : Message, tag : Int, name : String) -> Attribute?

    Message::find_group

    fn Message::find_group(self : Message, tag : Int) -> Group?

    Message::is_success

    fn Message::is_success(self : Message) -> Bool

    Message::new

    fn Message::new(code : Int, request_id : Int, groups : Array[Group]) -> Message

    Message::not_equal

    fn Message::not_equal(x : Message, y : Message) -> Bool

    Message::to_json

    fn Message::to_json(self : Message) -> Json

    Message::to_repr

    Message::with_document

    fn Message::with_document(self : Message, document : Bytes) -> Message

    MessageCollector

    pub struct MessageCollector {
    limits : DecodeLimits
    buffer :
    Buffer

    closed : Bool
    }

    finish must be called at HTTP EOF, not when a 0x03 byte appears in a document.

    MessageCollector::feed

    fn MessageCollector::feed(self : MessageCollector, chunk : Bytes) -> Unit raise IppError

    MessageCollector::finish

    MessageCollector::length

    fn MessageCollector::length(self : MessageCollector) -> Int

    MessageCollector::new

    Operation

    pub(all) enum Operation {
    PrintJob
    ValidateJob
    CreateJob
    SendDocument
    CancelJob
    GetJobAttributes
    GetJobs
    GetPrinterAttributes
    } derive(Eq,
    Debug
    )

    Operation::code

    fn Operation::code(self : Operation) -> Int

    Operation::equal

    fn Operation::equal(Operation, Operation) -> Bool

    Operation::name

    fn Operation::name(self : Operation) -> String

    Operation::not_equal

    fn Operation::not_equal(x : Operation, y : Operation) -> Bool

    PageRange

    pub(all) struct PageRange {
    first : Int
    last : Int
    } derive(Eq,
    Debug
    )

    PageRange::equal

    fn PageRange::equal(PageRange, PageRange) -> Bool

    PageRange::new

    fn PageRange::new(first : Int, last : Int) -> PageRange raise IppError

    PageRange::not_equal

    fn PageRange::not_equal(x : PageRange, y : PageRange) -> Bool

    PollPolicy

    pub(all) struct PollPolicy {
    interval_ms : Int
    maximum_polls : Int
    } derive(Eq,
    Debug
    )

    PollPolicy::defaults

    fn PollPolicy::defaults() -> PollPolicy

    PollPolicy::equal

    fn PollPolicy::equal(PollPolicy, PollPolicy) -> Bool

    PollPolicy::not_equal

    fn PollPolicy::not_equal(x : PollPolicy, y : PollPolicy) -> Bool

    PollPolicy::validate

    fn PollPolicy::validate(self : PollPolicy) -> Unit raise IppError

    PrintPlan

    pub(all) struct PrintPlan {
    printer : String
    options : JobOptions
    document_bytes : Int
    diagnostics : Array[Diagnostic]
    } derive(
    Debug
    )

    A plan is a preview, not permission to retry a network submission.

    PrintPlan::can_submit

    fn PrintPlan::can_submit(self : PrintPlan) -> Bool

    PrintPlan::to_json

    fn PrintPlan::to_json(self : PrintPlan) -> Json

    PrinterHealth

    pub(all) struct PrinterHealth {
    name : String
    state : PrinterState?
    accepting_jobs : Bool?
    queued_jobs : Int?
    reasons : Array[String]
    diagnostics : Array[Diagnostic]
    } derive(
    Debug
    )

    PrinterHealth::ready

    fn PrinterHealth::ready(self : PrinterHealth) -> Bool

    PrinterHealth::to_json

    fn PrinterHealth::to_json(self : PrinterHealth) -> Json

    PrinterState

    pub(all) enum PrinterState {
    Idle
    Processing
    Stopped
    Unrecognized(Int)
    } derive(Eq,
    Debug
    )

    PrinterState::equal

    PrinterState::not_equal

    fn PrinterState::not_equal(x : PrinterState, y : PrinterState) -> Bool

    PrinterState::text

    fn PrinterState::text(self : PrinterState) -> String

    PrinterUri

    pub(all) struct PrinterUri {
    scheme : String
    host : String
    port : Int
    path : String
    ipv6 : Bool
    } derive(Eq,
    Debug
    )

    PrinterUri::authority

    fn PrinterUri::authority(self : PrinterUri) -> String

    PrinterUri::equal

    fn PrinterUri::equal(PrinterUri, PrinterUri) -> Bool

    PrinterUri::http_url

    fn PrinterUri::http_url(self : PrinterUri) -> String

    PrinterUri::not_equal

    fn PrinterUri::not_equal(x : PrinterUri, y : PrinterUri) -> Bool

    PrinterUri::parse

    fn PrinterUri::parse(text : String) -> PrinterUri raise IppError

    PrinterUri::secure

    fn PrinterUri::secure(self : PrinterUri) -> Bool

    PrinterUri::text

    fn PrinterUri::text(self : PrinterUri) -> String

    QueueSummary

    pub(all) struct QueueSummary {
    total : Int
    pending : Int
    held : Int
    processing : Int
    stopped : Int
    canceled : Int
    aborted : Int
    completed : Int
    unknown : Int
    } derive(Eq,
    Debug
    )

    QueueSummary::equal

    QueueSummary::not_equal

    fn QueueSummary::not_equal(x : QueueSummary, y : QueueSummary) -> Bool

    QueueSummary::to_json

    fn QueueSummary::to_json(self : QueueSummary) -> Json

    RequestContext

    pub(all) struct RequestContext {
    printer : PrinterUri
    user : String
    language : String
    version : Version
    } derive(Eq,
    Debug
    )

    RequestContext::cancel_job

    fn RequestContext::cancel_job(self : RequestContext, request_id : Int, job_id : Int) -> Message raise IppError

    RequestContext::create_job

    fn RequestContext::create_job(self : RequestContext, request_id : Int, options : JobOptions) -> Message raise IppError

    RequestContext::equal

    RequestContext::get_jobs

    fn RequestContext::get_jobs(self : RequestContext, request_id : Int, which? : String, mine? : Bool, limit? : Int) -> Message raise IppError

    RequestContext::job_attributes

    fn RequestContext::job_attributes(self : RequestContext, request_id : Int, job_id : Int) -> Message raise IppError

    RequestContext::new

    fn RequestContext::new(uri : String, user? : String, language? : String) -> RequestContext raise IppError

    RequestContext::not_equal

    fn RequestContext::not_equal(x : RequestContext, y : RequestContext) -> Bool

    RequestContext::print_job

    fn RequestContext::print_job(self : RequestContext, request_id : Int, options : JobOptions, document : Bytes) -> Message raise IppError

    RequestContext::printer_attributes

    fn RequestContext::printer_attributes(self : RequestContext, request_id : Int, requested? : Array[String]) -> Message raise IppError

    RequestContext::send_document

    fn RequestContext::send_document(self : RequestContext, request_id : Int, job_id : Int, format : String, document : Bytes, last? : Bool) -> Message raise IppError

    RequestContext::validate_job

    fn RequestContext::validate_job(self : RequestContext, request_id : Int, options : JobOptions) -> Message raise IppError

    Resolution

    pub(all) struct Resolution {
    x : Int
    y : Int
    units : Int
    } derive(Eq,
    Debug
    )

    Resolution::dpi

    fn Resolution::dpi(x : Int, y : Int) -> Resolution raise IppError

    Resolution::equal

    fn Resolution::equal(Resolution, Resolution) -> Bool

    Resolution::not_equal

    fn Resolution::not_equal(x : Resolution, y : Resolution) -> Bool

    Severity

    pub(all) enum Severity {
    Warning
    Error
    } derive(Eq,
    Debug
    )

    Severity::equal

    fn Severity::equal(Severity, Severity) -> Bool

    Severity::not_equal

    fn Severity::not_equal(x : Severity, y : Severity) -> Bool

    Severity::to_repr

    Sides

    pub(all) enum Sides {
    OneSided
    TwoSidedLongEdge
    TwoSidedShortEdge
    } derive(Eq,
    Debug
    )

    Sides::equal

    fn Sides::equal(Sides, Sides) -> Bool

    Sides::keyword

    fn Sides::keyword(self : Sides) -> String

    Sides::not_equal

    fn Sides::not_equal(x : Sides, y : Sides) -> Bool

    Sides::to_repr

    SubmissionState

    pub(all) enum SubmissionState {
    NotSent
    Sending
    OutcomeUnknown
    Rejected(Int, String)
    Accepted(Job)
    } derive(Eq,
    Debug
    )

    SubmissionState::equal

    SubmissionState::may_submit_again

    fn SubmissionState::may_submit_again(self : SubmissionState) -> Bool

    SubmissionState::not_equal

    fn SubmissionState::not_equal(x : SubmissionState, y : SubmissionState) -> Bool

    Version

    pub(all) struct Version {
    major : Int
    minor : Int
    } derive(Eq,
    Debug
    )

    Version::equal

    fn Version::equal(Version, Version) -> Bool

    Version::new

    fn Version::new(major : Int, minor : Int) -> Version raise IppError

    Version::not_equal

    fn Version::not_equal(x : Version, y : Version) -> Bool

    Version::text

    fn Version::text(self : Version) -> String

    Version::to_repr

    Version::v11

    fn Version::v11() -> Version

    Version::v20

    fn Version::v20() -> Version

    bytes_from_hex

    fn bytes_from_hex(text : String) -> Bytes raise IppError

    bytes_to_hex

    fn bytes_to_hex(bytes : Bytes) -> String

    compare_capabilities

    fn compare_capabilities(before : Capabilities, after : Capabilities, include_volatile? : Bool) -> Array[CapabilityChange]

    decode

    fn decode(bytes : Bytes, limits? : DecodeLimits) -> Message raise IppError

    diagnostics_have_errors

    fn diagnostics_have_errors(diagnostics : Array[Diagnostic]) -> Bool

    encode

    fn encode(message : Message, limits? : DecodeLimits) -> Bytes raise IppError

    group_name

    fn group_name(tag : Int) -> String

    hex_dump

    fn hex_dump(bytes : Bytes, maximum? : Int, width? : Int) -> String raise IppError

    document bytes. The output limit prevents an accidental multi-megabyte log.

    infer_document_format

    fn infer_document_format(filename : String) -> String?

    is_safe_to_retry

    fn is_safe_to_retry(operation : Operation) -> Bool

    job_from_response

    fn job_from_response(response : Message) -> Job raise IppError

    job_state_from_code

    fn job_state_from_code(code : Int) -> JobState

    jobs_from_response

    fn jobs_from_response(response : Message) -> Array[Job] raise IppError

    media_spec_from_collection

    fn media_spec_from_collection(value : IppValue) -> MediaSpec raise IppError

    message_from_json

    fn message_from_json(json : Json, limits? : DecodeLimits) -> Message raise IppError

    operation_from_code

    fn operation_from_code(code : Int) -> Operation?

    parse_page_ranges

    fn parse_page_ranges(text : String) -> Array[PageRange] raise IppError

    printer_state_from_code

    fn printer_state_from_code(code : Int) -> PrinterState

    require_success

    fn require_success(response : Message) -> Unit raise IppError

    response_status_message

    fn response_status_message(response : Message) -> String

    sides_from_string

    fn sides_from_string(text : String) -> Sides raise IppError

    status_name

    fn status_name(code : Int) -> String

    summarize_queue

    fn summarize_queue(jobs : Array[Job]) -> QueueSummary raise IppError

    Summaries reject duplicate IDs instead of double-counting a malformed queue.

    unsupported_attributes

    fn unsupported_attributes(response : Message) -> Array[Attribute]

    valid_attribute_name

    fn valid_attribute_name(name : String) -> Bool

    valid_mime_type

    fn valid_mime_type(text : String) -> Bool

    validate_job_observation

    fn validate_job_observation(previous : Job?, current : Job) -> Unit raise IppError

    validate_request

    fn validate_request(request : Message) -> Unit raise IppError

    validate_response

    fn validate_response(request : Message, response : Message) -> Unit raise IppError

    value_tag_name

    fn value_tag_name(tag : Int) -> String

    volatile_printer_attribute

    fn volatile_printer_attribute(name : String) -> Bool

    with_media_collection

    fn with_media_collection(message : Message, spec : MediaSpec) -> Message raise IppError

    Add media-col without losing the operation attributes or document bytes.