moonformdata

Multipart parsing, upload contracts, compatibility analysis, conformance suites, and regression baselines for MoonBit.

multipart
form-data
upload
schema
conformance
api-governance
moon add ouoankang/moonformdata@0.1.0
Download zip
Author
Version
0.1.0
License
Apache-2.0
Last updated
11 hours ago
Downloads
2
README

#MoonFormData

MoonFormData 是一个 MoonBit 原生 multipart/form-data 表单解析、生成与上传契约治理工具包。它面向文件上传端点、Webhook、轻量网关、HTTP 客户端和 API 回归测试,把 multipart 请求转换为可校验、可演进、可追踪的应用层契约。

#生态定位

Mooncakes 已有 GCodinggo/moon-multipartSongyz002/moon-multipart,公开定位主要是 RFC 7578 字节流 parser/writer 与大文件传输。MoonFormData 不重复流式传输层,而是覆盖完整请求体进入应用后的治理流程。

能力层MoonFormData现有 moon-multipart 公开定位
数据处理有界内存请求体、结构化字段与文件模型Bytes、分块事件、流式 writer
端点规则命名 Schema、未知项策略、风险阈值、接受/拒绝决策RFC framing 与传输限制
API 演进契约版本差异、破坏性变更分级未作为主要能力公开
回归治理批量一致性套件、多端点目录、可保存基线、Markdown 报告未作为主要能力公开

项目为独立原创实现,不依赖、移植或复制上述包。完整对比见 生态定位与差异

#质量状态

项目状态
包名与版本ouoankang/moonformdata 0.1.0
主要语言核心功能全部使用 MoonBit 实现
代码规模9,000 行以上有效 MoonBit 代码
自动测试112 个,覆盖解析、错误、边界、安全、契约和治理流程
回归语料84 组项目自有合成 multipart fixture
示例cmd/mainexamples/basicexamples/governance
CI格式、零警告检查、构建、测试、JS 目标、接口漂移和示例
许可证Apache-2.0

#安装

moon add ouoankang/moonformdata

import {
"ouoankang/moonformdata" @moonformdata,
}

#解析示例

let body =
"--demo\r\n" +
"Content-Disposition: form-data; name=\"title\"\r\n" +
"\r\n" +
"MoonFormData\r\n" +
"--demo--\r\n"

match @moonformdata.parse_multipart(body, "demo") {
Ok(form) => println(form.require_field("title").unwrap())
Err(err) => println(err.message())
}

#上传契约示例

let schema = @moonformdata.strict_form_schema()
.add_field_rule(@moonformdata.required_field_rule("title"))
.add_file_rule(
@moonformdata.required_file_rule("upload")
.with_max_files(1)
.allow_content_type("text/plain")
.allow_extension("txt"),
)
let contract = @moonformdata.upload_contract(schema)
.with_max_risk(@moonformdata.LowRisk)

match @moonformdata.inspect_upload_request(request, contract) {
Ok(result) => println(result.decision_line())
Err(err) => println(err.message())
}

#契约治理示例

let diff = @moonformdata.compare_upload_contracts(v1_contract, v2_contract)
println(diff.summary())

let suite = @moonformdata.run_conformance_suite("avatar-v2", v2_contract, cases)
let baseline = @moonformdata.conformance_baseline(suite)
println(baseline.to_text())

完整示例同时演示契约差异、批量用例、多端点目录和基线比较:

moon run cmd/main moon run examples/basic moon run examples/governance

#主要功能

  • 解析 Content-Type boundary、Content-Disposition、part headers、filenamefilename*
  • 支持普通字段、重复字段、同名多文件、空文件、自定义 header、CRLF 与 LF-only 请求体
  • 生成 HTTP-ready multipart body,并提供字段、文件和 Builder API
  • 安全处理路径分隔符、盘符、控制字符、危险扩展名和超长文件名
  • 使用 ValidationPolicyFormSchema 校验必填项、数量、大小、类型、扩展名和未知项
  • 使用 UploadContract 组合解析限制、Schema、风险阈值和端点决策
  • 比较新旧契约,识别新增必填项、收紧限额、白名单缩小等破坏性变更
  • 运行接受、拒绝、解析失败、错误码和风险等级一致性用例
  • 按 HTTP 方法和路径管理多端点契约并生成一致性矩阵
  • 序列化回归基线,检测用例删除、结果变化、失败回归和错误码漂移
  • 输出稳定文本和 Markdown 报告,适合 CI、评审、Webhook 调试与 API 升级

#API 概览

分类主要 API
解析boundary_from_content_type, parse_multipart, parse_multipart_with_options, parse_multipart_request
生成encode_multipart, encode_fields_and_files, build_upload_request
查询field_value, field_values, files, require_field, require_file, summary
安全safe_filename, sanitize_filename_with_policy, strict_filename_policy
校验validate_form, validate_form_schema, field_rule, file_rule
分析analyze_form, FormAnalysis::to_lines, form_content_type_counts
上传契约upload_contract, inspect_upload, inspect_upload_request, UploadInspection::decision_line
契约演进compare_upload_contracts, ContractDiff::has_breaking_changes, ContractDiff::to_markdown
一致性套件upload_conformance_case, run_conformance_suite, ConformanceSuiteResult::to_markdown
多端点目录upload_endpoint, upload_contract_catalog, inspect_route, run_catalog_conformance
回归基线conformance_baseline, parse_conformance_baseline, compare_conformance_baseline

完整接口见 API 文档

#支持边界

支持:

  • 以 MoonBit String 为载体的有界内存请求体
  • 平面 multipart 表单、文本字段与文件字段
  • 默认目标与 JS 目标
  • 应用层 Schema、风险分析、契约演进和回归治理

不支持:

  • 完整 HTTP server
  • 任意二进制 Bytes 的流式大文件传输
  • 复杂嵌套 multipart 递归解析
  • 文件落盘、对象存储和云上传适配器
  • 浏览器 FormData 全量兼容矩阵

需要分块读取或大文件直传时,应选用流式 multipart 包;需要端点级验收、API 兼容性和稳定诊断时,可直接使用 MoonFormData,或把它放在 HTTP 适配层之后。

#错误模型

所有可能失败的解析 API 返回 Result[..., MultipartError],可区分缺少 boundary、非法 header、非法 Content-Type、非法 Content-Disposition、损坏 body 和超过限制。目录路由与基线格式另有结构化错误类型,便于生成 HTTP 响应、日志或 CI 失败信息。

#开发质量

moon fmt --check moon check --deny-warn moon build moon test --deny-warn moon check --target js moon build --target js moon test --target js moon run cmd/main moon run examples/basic moon run examples/governance moon info moon package --list

#文档

#开源合规

MoonFormData 采用 Apache-2.0 许可证。实现仅以 RFC 7578、RFC 2046、RFC 8187 等公开规范作为格式与行为依据;代码、示例、fixture 与测试均为项目原创或项目自有合成内容,不包含来源不明、私有或闭源代码。

#
BaselineChange

pub(all) struct BaselineChange {
impact : BaselineChangeImpact
kind : BaselineChangeKind
case_name : String
before : String
after : String
} derive(Eq,
Debug
)

One deterministic conformance baseline difference.

#
BaselineChange::to_line

fn BaselineChange::to_line(self : BaselineChange) -> String

#
BaselineChangeImpact

pub(all) enum BaselineChangeImpact {
BaselineCompatible
BaselineReview
BaselineRegression
} derive(Eq,
Debug
)

Impact assigned to a behavior change relative to a stored baseline.

#
BaselineChangeImpact::label

fn BaselineChangeImpact::label(self : BaselineChangeImpact) -> String

#
BaselineChangeKind

pub(all) enum BaselineChangeKind {
BaselineSuiteRenamed
BaselineCaseAdded
BaselineCaseRemoved
BaselineExpectationChanged
BaselineActualChanged
BaselinePassStatusChanged
BaselineIssueCodesChanged
} derive(Eq,
Debug
)

Kind of behavior change detected between a baseline and a current suite.

#
BaselineChangeKind::label

fn BaselineChangeKind::label(self : BaselineChangeKind) -> String

#
BaselineDiff

pub(all) struct BaselineDiff {
suite_name : String
changes : Array[BaselineChange]
} derive(Eq,
Debug
)

Complete baseline comparison for CI regression checks.

#
BaselineDiff::compatible_count

fn BaselineDiff::compatible_count(self : BaselineDiff) -> Int

#
BaselineDiff::has_regressions

fn BaselineDiff::has_regressions(self : BaselineDiff) -> Bool

#
BaselineDiff::is_unchanged

fn BaselineDiff::is_unchanged(self : BaselineDiff) -> Bool

#
BaselineDiff::regression_count

fn BaselineDiff::regression_count(self : BaselineDiff) -> Int

#
BaselineDiff::review_count

fn BaselineDiff::review_count(self : BaselineDiff) -> Int

#
BaselineDiff::summary

fn BaselineDiff::summary(self : BaselineDiff) -> String

#
BaselineDiff::to_lines

fn BaselineDiff::to_lines(self : BaselineDiff) -> Array[String]

#
BaselineDiff::to_markdown

fn BaselineDiff::to_markdown(self : BaselineDiff) -> String

Render a Markdown behavior-diff report for CI artifacts and code review.

#
BaselineError

pub(all) enum BaselineError {
InvalidBaselineHeader(String)
MissingBaselineSuite
InvalidBaselineLine(String)
InvalidBaselineExpectation(String)
InvalidBaselineActual(String)
InvalidBaselineStatus(String)
InvalidBaselineEscape(String)
} derive(Eq,
Debug
)

Parse errors for the stable MoonFormData conformance baseline format.

#
BaselineError::message

fn BaselineError::message(self : BaselineError) -> String

#
BodySizeClass

pub(all) enum BodySizeClass {
EmptyBody
TinyBody
SmallBody
MediumBody
LargeBody
} derive(Eq,
Debug
)

#
BodySizeClass::label

fn BodySizeClass::label(self : BodySizeClass) -> String

#
CatalogConformanceReport

pub(all) struct CatalogConformanceReport {
catalog_name : String
suites : Array[ConformanceSuiteResult]
issues : Array[String]
} derive(Eq,
Debug
)

Multi-endpoint conformance result for CI and API governance.

#
CatalogConformanceReport::case_count

#
CatalogConformanceReport::failed_count

fn CatalogConformanceReport::failed_count(self : CatalogConformanceReport) -> Int

#
CatalogConformanceReport::is_ok

#
CatalogConformanceReport::passed_count

fn CatalogConformanceReport::passed_count(self : CatalogConformanceReport) -> Int

#
CatalogConformanceReport::summary

#
CatalogConformanceReport::to_markdown

fn CatalogConformanceReport::to_markdown(self : CatalogConformanceReport) -> String

Render a multi-endpoint Markdown conformance matrix.

#
CatalogError

pub(all) enum CatalogError {
InvalidEndpointId(String)
InvalidEndpointMethod(String)
InvalidEndpointPath(String)
InvalidEndpointVersion(String)
DuplicateEndpointId(String)
DuplicateEndpointRoute(String)
EndpointNotFound(String)
} derive(Eq,
Debug
)

Validation and lookup errors produced by an upload contract catalog.

#
CatalogError::message

fn CatalogError::message(self : CatalogError) -> String

#
CatalogInspection

pub(all) struct CatalogInspection {
endpoint_id : String
endpoint_version : String
inspection : UploadInspection
} derive(Eq,
Debug
)

Successful routed inspection with endpoint identity preserved.

#
CatalogInspection::decision_line

fn CatalogInspection::decision_line(self : CatalogInspection) -> String

#
CatalogInspectionError

pub(all) enum CatalogInspectionError {
CatalogRoutingError(CatalogError)
CatalogUploadError(MultipartError)
} derive(Eq,
Debug
)

Request inspection errors distinguish routing failures from multipart failures.

#
CatalogInspectionError::message

fn CatalogInspectionError::message(self : CatalogInspectionError) -> String

#
ConformanceActual

pub(all) enum ConformanceActual {
ActualAccepted
ActualRejected
ActualParseError
} derive(Eq,
Debug
)

Observed outcome while running one upload contract conformance case.

#
ConformanceActual::label

fn ConformanceActual::label(self : ConformanceActual) -> String

#
ConformanceBaseline

pub(all) struct ConformanceBaseline {
suite_name : String
entries : Array[ConformanceBaselineEntry]
} derive(Eq,
Debug
)

Versioned, text-serializable snapshot of one conformance suite.

#
ConformanceBaseline::to_text

fn ConformanceBaseline::to_text(self : ConformanceBaseline) -> String

Serialize a baseline using a stable, line-oriented, diff-friendly format.

#
ConformanceBaselineEntry

pub(all) struct ConformanceBaselineEntry {
name : String
expectation : ConformanceExpectation
actual : ConformanceActual
passed : Bool
issue_codes : Array[String]
} derive(Eq,
Debug
)

Serializable behavior snapshot for one conformance case.

#
ConformanceCaseResult

pub(all) struct ConformanceCaseResult {
name : String
expectation : ConformanceExpectation
actual : ConformanceActual
passed : Bool
issue_codes : Array[String]
details : Array[String]
} derive(Eq,
Debug
)

Detailed result for one conformance case.

#
ConformanceCaseResult::status_label

fn ConformanceCaseResult::status_label(self : ConformanceCaseResult) -> String

#
ConformanceCaseResult::to_line

fn ConformanceCaseResult::to_line(self : ConformanceCaseResult) -> String

#
ConformanceExpectation

pub(all) enum ConformanceExpectation {
ExpectAccepted
ExpectRejected
ExpectParseError
} derive(Eq,
Debug
)

Expected outcome for one upload contract conformance case.

#
ConformanceExpectation::label

#
ConformanceSuiteResult

pub(all) struct ConformanceSuiteResult {
name : String
cases : Array[ConformanceCaseResult]
} derive(Eq,
Debug
)

Aggregate result for a deterministic batch of upload requests.

#
ConformanceSuiteResult::failed_cases

#
ConformanceSuiteResult::failed_count

fn ConformanceSuiteResult::failed_count(self : ConformanceSuiteResult) -> Int

#
ConformanceSuiteResult::is_ok

#
ConformanceSuiteResult::passed_count

fn ConformanceSuiteResult::passed_count(self : ConformanceSuiteResult) -> Int

#
ConformanceSuiteResult::summary

fn ConformanceSuiteResult::summary(self : ConformanceSuiteResult) -> String

#
ConformanceSuiteResult::to_lines

fn ConformanceSuiteResult::to_lines(self : ConformanceSuiteResult) -> Array[String]

#
ConformanceSuiteResult::to_markdown

fn ConformanceSuiteResult::to_markdown(self : ConformanceSuiteResult) -> String

Render a Markdown report suitable for CI artifacts and API review.

#
ContentDisposition

pub(all) struct ContentDisposition {
disposition : String
params : Array[(String, String)]
} derive(Eq,
Debug
)

Parsed Content-Disposition metadata for one multipart part.

#
ContentDisposition::param

fn ContentDisposition::param(self : ContentDisposition, name : String) -> String?

Return a disposition parameter by ASCII case-insensitive name.

#
ContentDisposition::parse

fn ContentDisposition::parse(header : String) -> Result[ContentDisposition, MultipartError]

Parse a Content-Disposition header.

#
ContractChange

pub(all) struct ContractChange {
impact : ContractChangeImpact
code : String
path : String
message : String
} derive(Eq,
Debug
)

One deterministic difference between two upload contracts.

#
ContractChange::to_line

fn ContractChange::to_line(self : ContractChange) -> String

#
ContractChangeImpact

pub(all) enum ContractChangeImpact {
CompatibleChange
ReviewChange
BreakingChange
} derive(Eq,
Debug
)

Compatibility impact assigned to one upload contract change.

#
ContractChangeImpact::label

fn ContractChangeImpact::label(self : ContractChangeImpact) -> String

#
ContractDiff

pub(all) struct ContractDiff {
changes : Array[ContractChange]
} derive(Eq,
Debug
)

Ordered compatibility report for an old and a new upload contract.

#
ContractDiff::breaking_count

fn ContractDiff::breaking_count(self : ContractDiff) -> Int

#
ContractDiff::compatible_count

fn ContractDiff::compatible_count(self : ContractDiff) -> Int

#
ContractDiff::has_breaking_changes

fn ContractDiff::has_breaking_changes(self : ContractDiff) -> Bool

#
ContractDiff::highest_impact

fn ContractDiff::highest_impact(self : ContractDiff) -> ContractChangeImpact

#
ContractDiff::is_unchanged

fn ContractDiff::is_unchanged(self : ContractDiff) -> Bool

#
ContractDiff::review_count

fn ContractDiff::review_count(self : ContractDiff) -> Int

#
ContractDiff::summary

fn ContractDiff::summary(self : ContractDiff) -> String

#
ContractDiff::to_lines

fn ContractDiff::to_lines(self : ContractDiff) -> Array[String]

#
ContractDiff::to_markdown

fn ContractDiff::to_markdown(self : ContractDiff) -> String

Render a review-friendly Markdown compatibility report.

#
EncodedForm

pub(all) struct EncodedForm {
content_type : String
body : String
boundary : String
} derive(Eq,
Debug
)

Result of encode_multipart.

#
EndpointConformancePlan

pub(all) struct EndpointConformancePlan {
endpoint_id : String
suite_name : String
cases : Array[UploadConformanceCase]
} derive(Eq,
Debug
)

Named conformance suite assigned to one catalog endpoint.

#
FieldProfile

pub(all) struct FieldProfile {
name : String
values : Int
total_length : Int
max_length : Int
empty_values : Int
duplicated : Bool
size_class : BodySizeClass
} derive(Eq,
Debug
)

#
FieldProfile::to_line

fn FieldProfile::to_line(self : FieldProfile) -> String

#
FieldRule

pub(all) struct FieldRule {
name : String
required : Bool
max_values : Int
max_length : Int
allow_empty : Bool
} derive(Eq,
Debug
)

#
FieldRule::with_allow_empty

fn FieldRule::with_allow_empty(self : FieldRule, allow_empty : Bool) -> FieldRule

#
FieldRule::with_max_length

fn FieldRule::with_max_length(self : FieldRule, max_length : Int) -> FieldRule

#
FieldRule::with_max_values

fn FieldRule::with_max_values(self : FieldRule, max_values : Int) -> FieldRule

#
FieldRule::with_required

fn FieldRule::with_required(self : FieldRule, required : Bool) -> FieldRule

#
FileProfile

pub(all) struct FileProfile {
name : String
filename : String
content_type : String
length : Int
empty : Bool
extension : String?
risk : UploadRisk
notes : Array[String]
size_class : BodySizeClass
} derive(Eq,
Debug
)

#
FileProfile::to_line

fn FileProfile::to_line(self : FileProfile) -> String

#
FileRule

pub(all) struct FileRule {
name : String
required : Bool
max_files : Int
max_length : Int
allowed_content_types : Array[String]
allowed_extensions : Array[String]
allow_empty : Bool
} derive(Eq,
Debug
)

#
FileRule::allow_content_type

fn FileRule::allow_content_type(self : FileRule, content_type : String) -> FileRule

#
FileRule::allow_extension

fn FileRule::allow_extension(self : FileRule, extension : String) -> FileRule

#
FileRule::with_allow_empty

fn FileRule::with_allow_empty(self : FileRule, allow_empty : Bool) -> FileRule

#
FileRule::with_max_files

fn FileRule::with_max_files(self : FileRule, max_files : Int) -> FileRule

#
FileRule::with_max_length

fn FileRule::with_max_length(self : FileRule, max_length : Int) -> FileRule

#
FileRule::with_required

fn FileRule::with_required(self : FileRule, required : Bool) -> FileRule

#
FileSpec

pub(all) struct FileSpec {
name : String
filename : String
content_type : String
body : String
} derive(Eq,
Debug
)

#
FilenamePolicy

pub(all) struct FilenamePolicy {
fallback : String
max_length : Int
allow_leading_dot : Bool
allow_spaces : Bool
allowed_extensions : Array[String]
blocked_extensions : Array[String]
} derive(Eq,
Debug
)

#
FormAnalysis

pub(all) struct FormAnalysis {
summary : FormSummary
fields : Array[FieldProfile]
files : Array[FileProfile]
content_types : Array[NameCount]
headers : Array[HeaderProfile]
risk : UploadRisk
notes : Array[String]
} derive(Eq,
Debug
)

#
FormAnalysis::compact_line

fn FormAnalysis::compact_line(self : FormAnalysis) -> String

#
FormAnalysis::has_note

fn FormAnalysis::has_note(self : FormAnalysis, needle : String) -> Bool

#
FormAnalysis::is_high_risk

fn FormAnalysis::is_high_risk(self : FormAnalysis) -> Bool

#
FormAnalysis::is_low_risk

fn FormAnalysis::is_low_risk(self : FormAnalysis) -> Bool

#
FormAnalysis::to_lines

fn FormAnalysis::to_lines(self : FormAnalysis) -> Array[String]

#
FormBuilder

pub(all) struct FormBuilder {
boundary : String?
parts : Array[FormPart]
} derive(Eq,
Debug
)

#
FormBuilder::add_empty_file

fn FormBuilder::add_empty_file(self : FormBuilder, name : String, filename : String, content_type? : String) -> FormBuilder

#
FormBuilder::add_field

fn FormBuilder::add_field(self : FormBuilder, name : String, value : String) -> FormBuilder

#
FormBuilder::add_file

fn FormBuilder::add_file(self : FormBuilder, name : String, filename : String, body : String, content_type? : String) -> FormBuilder

#
FormBuilder::add_part

fn FormBuilder::add_part(self : FormBuilder, part : FormPart) -> FormBuilder

#
FormBuilder::build

fn FormBuilder::build(self : FormBuilder) -> Result[EncodedForm, MultipartError]

#
FormBuilder::build_and_parse

fn FormBuilder::build_and_parse(self : FormBuilder) -> Result[MultipartForm, MultipartError]

#
FormBuilder::is_empty

fn FormBuilder::is_empty(self : FormBuilder) -> Bool

#
FormBuilder::new

#
FormBuilder::part_count

fn FormBuilder::part_count(self : FormBuilder) -> Int

#
FormBuilder::to_parts

fn FormBuilder::to_parts(self : FormBuilder) -> Array[FormPart]

#
FormBuilder::with_boundary

fn FormBuilder::with_boundary(self : FormBuilder, boundary : String) -> Result[FormBuilder, MultipartError]

#
FormPart

pub(all) struct FormPart {
name : String
filename : String?
content_type : String?
headers : Array[(String, String)]
body : String
} derive(Eq,
Debug
)

A single multipart part. File uploads have a filename; ordinary form fields do not.

#
FormPart::body_length

fn FormPart::body_length(self : FormPart) -> Int

#
FormPart::content_type_or

fn FormPart::content_type_or(self : FormPart, fallback : String) -> String

#
FormPart::debug_line

fn FormPart::debug_line(self : FormPart) -> String

#
FormPart::disposition_header

fn FormPart::disposition_header(self : FormPart) -> String

#
FormPart::encoded_header_block

fn FormPart::encoded_header_block(self : FormPart) -> Result[String, MultipartError]

#
FormPart::filename_or

fn FormPart::filename_or(self : FormPart, fallback : String) -> String

#
FormPart::has_header

fn FormPart::has_header(self : FormPart, name : String) -> Bool

#
FormPart::header

fn FormPart::header(self : FormPart, name : String) -> String?

#
FormPart::is_empty

fn FormPart::is_empty(self : FormPart) -> Bool

#
FormPart::is_file

fn FormPart::is_file(self : FormPart) -> Bool

#
FormPart::is_text_field

fn FormPart::is_text_field(self : FormPart) -> Bool

#
FormPart::safe_filename

fn FormPart::safe_filename(self : FormPart) -> String?

#
FormSchema

pub(all) struct FormSchema {
field_rules : Array[FieldRule]
file_rules : Array[FileRule]
allow_unknown_fields : Bool
allow_unknown_files : Bool
} derive(Eq,
Debug
)

#
FormSchema::add_field_rule

fn FormSchema::add_field_rule(self : FormSchema, rule : FieldRule) -> FormSchema

#
FormSchema::add_file_rule

fn FormSchema::add_file_rule(self : FormSchema, rule : FileRule) -> FormSchema

#
FormSchema::with_unknown_fields

fn FormSchema::with_unknown_fields(self : FormSchema, allow : Bool) -> FormSchema

#
FormSchema::with_unknown_files

fn FormSchema::with_unknown_files(self : FormSchema, allow : Bool) -> FormSchema

#
FormSummary

pub(all) struct FormSummary {
part_count : Int
field_count : Int
file_count : Int
empty_file_count : Int
total_body_length : Int
distinct_name_count : Int
} derive(Eq,
Debug
)

#
FormSummary::to_line

fn FormSummary::to_line(self : FormSummary) -> String

#
HeaderProfile

pub(all) struct HeaderProfile {
name : String
count : Int
first_value : String
} derive(Eq,
Debug
)

#
HeaderProfile::to_line

fn HeaderProfile::to_line(self : HeaderProfile) -> String

#
MediaType

pub(all) struct MediaType {
typ : String
subtype : String
params : Array[(String, String)]
} derive(Eq,
Debug
)

A parsed Content-Type or part-level media type value.

#
MediaType::param

fn MediaType::param(self : MediaType, name : String) -> String?

Return a parameter by ASCII case-insensitive name.

#
MediaType::parse

fn MediaType::parse(header : String) -> Result[MediaType, MultipartError]

Parse a media type such as multipart/form-data; boundary=abc.

#
MultipartError

pub(all) enum MultipartError {
MissingBoundary
InvalidBoundary(String)
InvalidHeader(String)
InvalidContentType(String)
InvalidContentDisposition(String)
MalformedBody(String)
LimitExceeded(String)
} derive(Eq,
Debug
)

Structured errors make validation failures explainable in examples and CI.

#
MultipartError::message

fn MultipartError::message(self : MultipartError) -> String

Human-readable error message for logs, CLI examples, and HTTP 400 replies.

#
MultipartFixture

pub(all) struct MultipartFixture {
name : String
boundary : String
body : String
expected_parts : Int
expected_fields : Int
expected_files : Int
} derive(Eq,
Debug
)

#
MultipartForm

pub(all) struct MultipartForm {
boundary : String
parts : Array[FormPart]
} derive(Eq,
Debug
)

Parsed form data. parts preserves wire order, including repeated fields.

#
MultipartForm::debug_lines

fn MultipartForm::debug_lines(self : MultipartForm) -> Array[String]

#
MultipartForm::empty_file_count

fn MultipartForm::empty_file_count(self : MultipartForm) -> Int

#
MultipartForm::field_count

fn MultipartForm::field_count(self : MultipartForm) -> Int

#
MultipartForm::field_names

fn MultipartForm::field_names(self : MultipartForm) -> Array[String]

#
MultipartForm::field_value

fn MultipartForm::field_value(self : MultipartForm, name : String) -> String?

Return the first ordinary form field value.

#
MultipartForm::field_value_or

fn MultipartForm::field_value_or(self : MultipartForm, name : String, fallback : String) -> String

#
MultipartForm::field_values

fn MultipartForm::field_values(self : MultipartForm, name : String) -> Array[String]

Return all values for an ordinary form field.

#
MultipartForm::file_count

fn MultipartForm::file_count(self : MultipartForm) -> Int

#
MultipartForm::file_field_names

fn MultipartForm::file_field_names(self : MultipartForm) -> Array[String]

#
MultipartForm::file_parts

fn MultipartForm::file_parts(self : MultipartForm) -> Array[FormPart]

#
MultipartForm::files

fn MultipartForm::files(self : MultipartForm, name : String) -> Array[FormPart]

Return file parts for a given field name.

#
MultipartForm::first_part

fn MultipartForm::first_part(self : MultipartForm, name : String) -> FormPart?

#
MultipartForm::has_duplicate_field

fn MultipartForm::has_duplicate_field(self : MultipartForm, name : String) -> Bool

#
MultipartForm::has_duplicate_file_field

fn MultipartForm::has_duplicate_file_field(self : MultipartForm, name : String) -> Bool

#
MultipartForm::has_field

fn MultipartForm::has_field(self : MultipartForm, name : String) -> Bool

#
MultipartForm::has_file

fn MultipartForm::has_file(self : MultipartForm, name : String) -> Bool

#
MultipartForm::is_empty

fn MultipartForm::is_empty(self : MultipartForm) -> Bool

#
MultipartForm::names

fn MultipartForm::names(self : MultipartForm) -> Array[String]

#
MultipartForm::part_count

fn MultipartForm::part_count(self : MultipartForm) -> Int

#
MultipartForm::parts_named

fn MultipartForm::parts_named(self : MultipartForm, name : String) -> Array[FormPart]

#
MultipartForm::require_field

fn MultipartForm::require_field(self : MultipartForm, name : String) -> Result[String, MultipartError]

#
MultipartForm::require_file

fn MultipartForm::require_file(self : MultipartForm, name : String) -> Result[FormPart, MultipartError]

#
MultipartForm::summary

fn MultipartForm::summary(self : MultipartForm) -> FormSummary

#
MultipartForm::text_parts

fn MultipartForm::text_parts(self : MultipartForm) -> Array[FormPart]

#
MultipartForm::total_body_length

fn MultipartForm::total_body_length(self : MultipartForm) -> Int

#
MultipartForm::validate

#
MultipartForm::validate_schema

fn MultipartForm::validate_schema(self : MultipartForm, schema : FormSchema) -> ValidationReport

#
MultipartRequest

pub(all) struct MultipartRequest {
content_type : String
body : String
} derive(Eq,
Debug
)

#
NameCount

pub(all) struct NameCount {
name : String
count : Int
} derive(Eq,
Debug
)

#
ParseAndValidateResult

pub(all) struct ParseAndValidateResult {
form : MultipartForm
report : ValidationReport
} derive(Eq,
Debug
)

#
ParseOptions

pub(all) struct ParseOptions {
max_parts : Int
max_headers_per_part : Int
max_body_length : Int
} derive(Eq,
Debug
)

Parser limits for the in-memory v1 implementation.

#
RegressionFixtureSpec

pub(all) struct RegressionFixtureSpec {
label : String
boundary : String
title : String
tag : String
filename : String
file_body : String
} derive(Eq,
Debug
)

#
UploadConformanceCase

pub(all) struct UploadConformanceCase {
name : String
content_type : String
body : String
expectation : ConformanceExpectation
required_issue_codes : Array[String]
expected_risk : UploadRisk?
} derive(Eq,
Debug
)

One named multipart request and its expected contract behavior.

#
UploadConformanceCase::require_issue_code

fn UploadConformanceCase::require_issue_code(self : UploadConformanceCase, code : String) -> UploadConformanceCase

Require a schema issue code to appear when this case is inspected.

#
UploadConformanceCase::with_expected_risk

Require the form analysis to produce a specific risk level.

#
UploadContract

pub(all) struct UploadContract {
parse_options : ParseOptions
schema : FormSchema
max_risk : UploadRisk
} derive(Eq,
Debug
)

Application-facing multipart contract.

A contract combines parser limits, a named form schema, and the highest analysis risk accepted by an endpoint.

#
UploadContract::with_max_risk

fn UploadContract::with_max_risk(self : UploadContract, max_risk : UploadRisk) -> UploadContract

Set the highest analysis risk accepted by a contract.

#
UploadContract::with_parse_options

fn UploadContract::with_parse_options(self : UploadContract, parse_options : ParseOptions) -> UploadContract

Replace the parser limits used by a contract.

#
UploadContract::with_schema

fn UploadContract::with_schema(self : UploadContract, schema : FormSchema) -> UploadContract

Replace the declarative form schema used by a contract.

#
UploadContractCatalog

pub(all) struct UploadContractCatalog {
endpoints : Array[UploadEndpoint]
} derive(Eq,
Debug
)

Immutable-style collection of upload endpoint contracts.

#
UploadContractCatalog::add

Add one endpoint while rejecting duplicate IDs and routes.

#
UploadContractCatalog::endpoint_count

fn UploadContractCatalog::endpoint_count(self : UploadContractCatalog) -> Int

#
UploadContractCatalog::find_by_id

fn UploadContractCatalog::find_by_id(self : UploadContractCatalog, id : String) -> UploadEndpoint?

Return an endpoint by stable catalog ID.

#
UploadContractCatalog::find_route

fn UploadContractCatalog::find_route(self : UploadContractCatalog, http_method : String, path : String) -> UploadEndpoint?

Return an endpoint by normalized HTTP method and exact path.

#
UploadContractCatalog::inspect_route

fn UploadContractCatalog::inspect_route(self : UploadContractCatalog, http_method : String, path : String, request : MultipartRequest) -> Result[CatalogInspection, CatalogInspectionError]

Route and inspect a multipart request using the matching endpoint contract.

#
UploadContractCatalog::to_lines

fn UploadContractCatalog::to_lines(self : UploadContractCatalog) -> Array[String]

#
UploadDecision

pub(all) enum UploadDecision {
UploadAccepted
UploadRejected
} derive(Eq,
Debug
)

Final decision produced by an upload contract inspection.

#
UploadDecision::label

fn UploadDecision::label(self : UploadDecision) -> String

#
UploadEndpoint

pub(all) struct UploadEndpoint {
id : String
http_method : String
path : String
version : String
contract : UploadContract
} derive(Eq,
Debug
)

One versioned upload endpoint and its application-facing contract.

#
UploadEndpoint::label

fn UploadEndpoint::label(self : UploadEndpoint) -> String

#
UploadEndpoint::route_key

fn UploadEndpoint::route_key(self : UploadEndpoint) -> String

#
UploadInspection

pub(all) struct UploadInspection {
form : MultipartForm
validation : ValidationReport
analysis : FormAnalysis
max_risk : UploadRisk
decision : UploadDecision
} derive(Eq,
Debug
)

Complete result of parsing and checking one upload request.

#
UploadInspection::decision_line

fn UploadInspection::decision_line(self : UploadInspection) -> String

Stable one-line result for logs, CI output, and webhook diagnostics.

#
UploadInspection::is_accepted

fn UploadInspection::is_accepted(self : UploadInspection) -> Bool

#
UploadInspection::rejection_reasons

fn UploadInspection::rejection_reasons(self : UploadInspection) -> Array[String]

Explain every reason why an otherwise parseable request was rejected.

#
UploadInspection::status_code

fn UploadInspection::status_code(self : UploadInspection) -> Int

A conventional status code for endpoint adapters.

#
UploadInspection::to_lines

fn UploadInspection::to_lines(self : UploadInspection) -> Array[String]

Render a deterministic inspection report.

#
UploadRisk

pub(all) enum UploadRisk {
LowRisk
MediumRisk
HighRisk
} derive(Eq,
Debug
)

#
UploadRisk::label

fn UploadRisk::label(self : UploadRisk) -> String

#
ValidationIssue

pub(all) struct ValidationIssue {
code : String
message : String
part_index : Int?
field_name : String?
} derive(Eq,
Debug
)

#
ValidationIssue::to_line

fn ValidationIssue::to_line(self : ValidationIssue) -> String

#
ValidationPolicy

pub(all) struct ValidationPolicy {
required_fields : Array[String]
required_files : Array[String]
allowed_file_content_types : Array[String]
max_text_length : Int
max_file_length : Int
max_filename_length : Int
allow_empty_files : Bool
allow_duplicate_fields : Bool
allow_duplicate_files : Bool
} derive(Eq,
Debug
)

#
ValidationReport

pub(all) struct ValidationReport {
issues : Array[ValidationIssue]
} derive(Eq,
Debug
)

#
ValidationReport::first_message

fn ValidationReport::first_message(self : ValidationReport) -> String?

#
ValidationReport::has_issue_code

fn ValidationReport::has_issue_code(self : ValidationReport, code : String) -> Bool

#
ValidationReport::is_ok

fn ValidationReport::is_ok(self : ValidationReport) -> Bool

#
ValidationReport::issue_count

fn ValidationReport::issue_count(self : ValidationReport) -> Int

#
ValidationReport::issues_for_field

fn ValidationReport::issues_for_field(self : ValidationReport, name : String) -> Array[ValidationIssue]

#
ValidationReport::messages

fn ValidationReport::messages(self : ValidationReport) -> Array[String]

#
ValidationReport::summary

fn ValidationReport::summary(self : ValidationReport) -> String

#
ValidationReport::to_lines

fn ValidationReport::to_lines(self : ValidationReport) -> Array[String]

#
accept_upload_request

fn accept_upload_request(request : MultipartRequest, policy : ValidationPolicy) -> Result[String, MultipartError]

#
analyze_form

fn analyze_form(form : MultipartForm) -> FormAnalysis

#
analyze_request

fn analyze_request(request : MultipartRequest) -> Result[FormAnalysis, MultipartError]

#
assert_fixture_shape

fn assert_fixture_shape(fixture : MultipartFixture) -> Result[FormSummary, MultipartError]

#
bad_request_message

fn bad_request_message(err : MultipartError) -> String

#
binary_file_spec

fn binary_file_spec(name : String, filename : String, body : String) -> FileSpec

#
body_size_class

fn body_size_class(length : Int) -> BodySizeClass

#
boundary_from_content_type

fn boundary_from_content_type(header : String) -> Result[String, MultipartError]

Parse Content-Type and extract the boundary parameter.

#
build_request_from_fields

fn build_request_from_fields(fields : Array[(String, String)], boundary? : String) -> Result[MultipartRequest, MultipartError]

#
build_upload_request

fn build_upload_request(fields : Array[(String, String)], files : Array[FileSpec], boundary? : String) -> Result[MultipartRequest, MultipartError]

#
collect_file_names

fn collect_file_names(form : MultipartForm) -> Array[String]

#
collect_text_pairs

fn collect_text_pairs(form : MultipartForm) -> Array[(String, String)]

#
compare_conformance_baseline

fn compare_conformance_baseline(previous : ConformanceBaseline, current : ConformanceSuiteResult) -> BaselineDiff

Compare a stored baseline with a newly executed conformance suite.

#
compare_upload_contracts

fn compare_upload_contracts(previous : UploadContract, current : UploadContract) -> ContractDiff

Compare two endpoint contracts and classify compatibility changes.

#
conformance_baseline

fn conformance_baseline(suite : ConformanceSuiteResult) -> ConformanceBaseline

Capture the observable result of a conformance suite.

#
count_by_name

fn count_by_name(values : Array[String]) -> Array[NameCount]

#
decode_percent_ascii

fn decode_percent_ascii(value : String) -> Result[String, MultipartError]

#
decode_rfc5987_value

fn decode_rfc5987_value(value : String) -> Result[String, MultipartError]

#
default_filename_policy

fn default_filename_policy() -> FilenamePolicy

#
default_form_schema

fn default_form_schema() -> FormSchema

#
default_parse_options

fn default_parse_options() -> ParseOptions

Conservative defaults for small and medium form payloads.

#
default_validation_policy

fn default_validation_policy() -> ValidationPolicy

#
detect_boundary_in_part_bodies

fn detect_boundary_in_part_bodies(form : MultipartForm) -> Bool

#
empty_file_part

fn empty_file_part(name : String, filename : String, content_type? : String) -> FormPart

#
encode_fields

fn encode_fields(fields : Array[(String, String)], boundary? : String) -> Result[EncodedForm, MultipartError]

#
encode_fields_and_files

fn encode_fields_and_files(fields : Array[(String, String)], files : Array[FileSpec], boundary? : String) -> Result[EncodedForm, MultipartError]

#
encode_files

fn encode_files(files : Array[FileSpec], boundary? : String) -> Result[EncodedForm, MultipartError]

#
encode_multipart

fn encode_multipart(parts : Array[FormPart], boundary? : String) -> Result[EncodedForm, MultipartError]

Build a multipart body. The returned content_type is ready for HTTP use.

#
encode_rfc5987_value

fn encode_rfc5987_value(value : String) -> String

#
encoded_to_request

fn encoded_to_request(encoded : EncodedForm) -> MultipartRequest

#
endpoint_conformance_plan

fn endpoint_conformance_plan(endpoint_id : String, suite_name : String, cases : Array[UploadConformanceCase]) -> EndpointConformancePlan

Create a conformance plan for one endpoint ID.

#
field_rule

fn field_rule(name : String) -> FieldRule

#
file_part

fn file_part(name : String, filename : String, body : String, content_type? : String) -> FormPart

#
file_rule

fn file_rule(name : String) -> FileRule

#
file_spec

fn file_spec(name : String, filename : String, content_type : String, body : String) -> FileSpec

#
filename_contains_path_separator

fn filename_contains_path_separator(filename : String) -> Bool

#
filename_extension

fn filename_extension(filename : String) -> String?

#
filename_from_disposition

fn filename_from_disposition(disposition : ContentDisposition) -> String?

#
filename_has_allowed_extension

fn filename_has_allowed_extension(filename : String, allowed : Array[String]) -> Bool

#
filename_has_control_chars

fn filename_has_control_chars(filename : String) -> Bool

#
filename_has_extension

fn filename_has_extension(filename : String, extension : String) -> Bool

#
filename_looks_like_windows_drive

fn filename_looks_like_windows_drive(filename : String) -> Bool

#
filename_security_notes

fn filename_security_notes(filename : String) -> Array[String]

#
filename_stem

fn filename_stem(filename : String) -> String

#
find_name_count

fn find_name_count(counts : Array[NameCount], name : String) -> Int

#
fixture_custom_headers

fn fixture_custom_headers() -> MultipartFixture

#
fixture_empty_file

fn fixture_empty_file() -> MultipartFixture

#
fixture_file_upload

fn fixture_file_upload() -> MultipartFixture

#
fixture_mixed_upload

fn fixture_mixed_upload() -> MultipartFixture

#
fixture_quoted_boundary

fn fixture_quoted_boundary() -> (String, String)

#
fixture_simple_fields

fn fixture_simple_fields() -> MultipartFixture

#
fixture_status_line

fn fixture_status_line(fixture : MultipartFixture) -> String

#
fixture_to_request

fn fixture_to_request(fixture : MultipartFixture) -> MultipartRequest

#
form_content_type_counts

fn form_content_type_counts(form : MultipartForm) -> Array[NameCount]

#
form_debug_report

fn form_debug_report(form : MultipartForm) -> Array[String]

#
form_name_counts

fn form_name_counts(form : MultipartForm) -> Array[NameCount]

#
form_schema_require_field

fn form_schema_require_field(schema : FormSchema, name : String) -> FormSchema

#
form_schema_require_file

fn form_schema_require_file(schema : FormSchema, name : String) -> FormSchema

#
format_content_disposition

fn format_content_disposition(disposition : ContentDisposition) -> String

#
format_media_type

fn format_media_type(media : MediaType) -> String

#
has_header

fn has_header(headers : Array[(String, String)], name : String) -> Bool

#
header_names

fn header_names(headers : Array[(String, String)]) -> Array[String]

#
image_filename_policy

fn image_filename_policy() -> FilenamePolicy

#
inspect_parsed_form

fn inspect_parsed_form(form : MultipartForm, contract : UploadContract) -> UploadInspection

Inspect an already parsed form without parsing it again.

#
inspect_upload

fn inspect_upload(content_type : String, body : String, contract : UploadContract) -> Result[UploadInspection, MultipartError]

Parse and inspect a raw multipart request using one upload contract.

#
inspect_upload_request

fn inspect_upload_request(request : MultipartRequest, contract : UploadContract) -> Result[UploadInspection, MultipartError]

Parse and inspect a request using one application-facing upload contract.

#
is_multipart_form_data_content_type

fn is_multipart_form_data_content_type(header : String) -> Bool

#
media_type_without_params

fn media_type_without_params(header : String) -> Result[String, MultipartError]

#
new_form_builder

fn new_form_builder() -> FormBuilder

#
normalize_header_name

fn normalize_header_name(name : String) -> String

#
ok_request_message

fn ok_request_message(form : MultipartForm) -> String

#
parse_and_validate_request

fn parse_and_validate_request(content_type : String, body : String, policy : ValidationPolicy) -> Result[ParseAndValidateResult, MultipartError]

#
parse_and_validate_schema_request

fn parse_and_validate_schema_request(content_type : String, body : String, schema : FormSchema) -> Result[ParseAndValidateResult, MultipartError]

#
parse_conformance_baseline

fn parse_conformance_baseline(source : String) -> Result[ConformanceBaseline, BaselineError]

Parse a baseline previously produced by ConformanceBaseline::to_text.

#
parse_content_disposition_header

fn parse_content_disposition_header(value : String) -> Result[ContentDisposition, MultipartError]

#
parse_fixture

fn parse_fixture(fixture : MultipartFixture) -> Result[MultipartForm, MultipartError]

#
parse_media_type_header

fn parse_media_type_header(value : String) -> Result[MediaType, MultipartError]

#
parse_multipart

fn parse_multipart(body : String, boundary : String) -> Result[MultipartForm, MultipartError]

Parse an in-memory multipart body with conservative default limits.

#
parse_multipart_request

fn parse_multipart_request(content_type : String, body : String) -> Result[MultipartForm, MultipartError]

#
parse_multipart_request_with_options

fn parse_multipart_request_with_options(content_type : String, body : String, options : ParseOptions) -> Result[MultipartForm, MultipartError]

#
parse_multipart_with_options

fn parse_multipart_with_options(body : String, boundary : String, options : ParseOptions) -> Result[MultipartForm, MultipartError]

Parse an in-memory multipart body with caller-provided limits.

#
part_add_header

fn part_add_header(part : FormPart, name : String, value : String) -> Result[FormPart, MultipartError]

#
part_remove_header

fn part_remove_header(part : FormPart, name : String) -> FormPart

#
part_replace_header

fn part_replace_header(part : FormPart, name : String, value : String) -> Result[FormPart, MultipartError]

#
part_with_body

fn part_with_body(part : FormPart, body : String) -> FormPart

#
part_with_content_type

fn part_with_content_type(part : FormPart, content_type : String) -> FormPart

#
part_with_filename

fn part_with_filename(part : FormPart, filename : String) -> FormPart

#
part_with_name

fn part_with_name(part : FormPart, name : String) -> FormPart

#
part_without_content_type

fn part_without_content_type(part : FormPart) -> FormPart

#
part_without_filename

fn part_without_filename(part : FormPart) -> FormPart

#
percent_encode_header_value

fn percent_encode_header_value(value : String) -> String

#
quote_header_value

fn quote_header_value(value : String) -> String

#
raw_upload_conformance_case

fn raw_upload_conformance_case(name : String, content_type : String, body : String, expectation : ConformanceExpectation) -> UploadConformanceCase

Build a conformance case directly from HTTP Content-Type and body values.

#
regression_fixture_count

fn regression_fixture_count() -> Int

#
regression_fixture_from_spec

fn regression_fixture_from_spec(spec : RegressionFixtureSpec) -> MultipartFixture

#
regression_fixture_names

fn regression_fixture_names() -> Array[String]

#
regression_fixtures

fn regression_fixtures() -> Array[MultipartFixture]

#
regression_specs

fn regression_specs() -> Array[RegressionFixtureSpec]

#
remove_header

fn remove_header(headers : Array[(String, String)], name : String) -> Array[(String, String)]

#
request_analysis_lines

fn request_analysis_lines(request : MultipartRequest) -> Result[Array[String], MultipartError]

#
request_boundary

fn request_boundary(request : MultipartRequest) -> Result[String, MultipartError]

#
request_content_length

fn request_content_length(request : MultipartRequest) -> Int

#
request_debug_report

fn request_debug_report(request : MultipartRequest) -> Result[Array[String], MultipartError]

#
request_has_multipart_content_type

fn request_has_multipart_content_type(request : MultipartRequest) -> Bool

#
request_with_body

fn request_with_body(request : MultipartRequest, body : String) -> MultipartRequest

#
request_with_content_type

fn request_with_content_type(request : MultipartRequest, content_type : String) -> MultipartRequest

#
require_single_field

fn require_single_field(form : MultipartForm, name : String) -> Result[String, MultipartError]

#
require_single_file

fn require_single_file(form : MultipartForm, name : String) -> Result[FormPart, MultipartError]

#
required_field_rule

fn required_field_rule(name : String) -> FieldRule

#
required_file_rule

fn required_file_rule(name : String) -> FileRule

#
roundtrip_request

fn roundtrip_request(request : MultipartRequest) -> Result[MultipartForm, MultipartError]

#
run_catalog_conformance

fn run_catalog_conformance(catalog_name : String, catalog : UploadContractCatalog, plans : Array[EndpointConformancePlan]) -> CatalogConformanceReport

Run conformance plans against every referenced endpoint in a catalog.

#
run_conformance_suite

fn run_conformance_suite(name : String, contract : UploadContract, cases : Array[UploadConformanceCase]) -> ConformanceSuiteResult

Run a named batch of multipart requests against one upload contract.

#
safe_filename

fn safe_filename(filename : String) -> String

Remove path separators, drive prefixes, and control characters from a client supplied filename. Returns "upload.bin" when no safe character remains.

#
sanitize_filename_with_policy

fn sanitize_filename_with_policy(filename : String, policy : FilenamePolicy) -> String

#
set_header

fn set_header(headers : Array[(String, String)], name : String, value : String) -> Result[Array[(String, String)], MultipartError]

#
standard_fixtures

fn standard_fixtures() -> Array[MultipartFixture]

#
strict_filename_policy

fn strict_filename_policy() -> FilenamePolicy

#
strict_form_schema

fn strict_form_schema() -> FormSchema

#
strict_validation_policy

fn strict_validation_policy() -> ValidationPolicy

#
text_file_spec

fn text_file_spec(name : String, filename : String, body : String) -> FileSpec

#
text_part

fn text_part(name : String, value : String) -> FormPart

#
upload_conformance_case

fn upload_conformance_case(name : String, request : MultipartRequest, expectation : ConformanceExpectation) -> UploadConformanceCase

Build a conformance case from a generated or captured request wrapper.

#
upload_contract

fn upload_contract(schema : FormSchema) -> UploadContract

Create a contract with conservative parser limits and a medium risk ceiling.

#
upload_contract_catalog

fn upload_contract_catalog() -> UploadContractCatalog

Create an empty upload contract catalog.

#
upload_endpoint

fn upload_endpoint(id : String, http_method : String, path : String, version : String, contract : UploadContract) -> Result[UploadEndpoint, CatalogError]

Create and validate one endpoint catalog entry.

#
upload_risk_at_most

fn upload_risk_at_most(actual : UploadRisk, maximum : UploadRisk) -> Bool

#
validate_form

fn validate_form(form : MultipartForm, policy : ValidationPolicy) -> ValidationReport

#
validate_form_schema

fn validate_form_schema(form : MultipartForm, schema : FormSchema) -> ValidationReport

#
validate_upload_request

fn validate_upload_request(request : MultipartRequest, policy : ValidationPolicy) -> Result[ValidationReport, MultipartError]

#
validation_issue

fn validation_issue(code : String, message : String, part_index? : Int, field_name? : String) -> ValidationIssue

#
validation_policy_allow_file_type

fn validation_policy_allow_file_type(policy : ValidationPolicy, content_type : String) -> ValidationPolicy

#
validation_policy_require_field

fn validation_policy_require_field(policy : ValidationPolicy, name : String) -> ValidationPolicy

#
validation_policy_require_file

fn validation_policy_require_file(policy : ValidationPolicy, name : String) -> ValidationPolicy

#
webhook_summary

fn webhook_summary(content_type : String, body : String) -> Result[String, MultipartError]