section_delim = _{ "---" }
whitespace = _{ " " | "\t" }
identifier = @{ (ASCII_ALPHA | "_") ~ (ASCII_ALPHANUMERIC | "_")* }
collection_name = { "name" ~ whitespace* ~ "=" ~ whitespace* ~ value ~ NEWLINE }
collection_description = { "description" ~ whitespace* ~ "=" ~ whitespace* ~ value }
variable = { "$" ~ whitespace* ~ key ~ whitespace* ~ "=" ~ whitespace* ~ value }
env_variable = { whitespace* ~ "$" ~ whitespace* ~ key ~ whitespace* ~ "=" ~ whitespace* ~ value }
environment_block = { "env" ~ whitespace+ ~ identifier ~ NEWLINE+ ~ env_variable ~ (NEWLINE+ ~ env_variable)* }
oauth_assignment = { whitespace* ~ identifier ~ whitespace* ~ "=" ~ whitespace* ~ value }
oauth_param = { whitespace* ~ "param" ~ whitespace+ ~ identifier ~ whitespace* ~ "=" ~ whitespace* ~ value }
oauth_target_variable = { "$" ~ whitespace* ~ identifier }
oauth_field_mapping = { whitespace* ~ identifier ~ whitespace* ~ "->" ~ whitespace* ~ oauth_target_variable }
oauth_item = _{ oauth_param | oauth_field_mapping | oauth_assignment }
oauth_block = { "oauth" ~ whitespace+ ~ identifier ~ NEWLINE+ ~ oauth_item ~ (NEWLINE+ ~ oauth_item)* }
cookie = { "@" ~ whitespace* ~ key ~ whitespace* ~ "=" ~ whitespace* ~ value }
key = { (!"=" ~ ANY)+ }
value = { (!"\n" ~ ANY)+ }
quoted_string = @{ ("\"" ~ ("\\\"" | !("\"" | NEWLINE) ~ ANY)* ~ "\"") | ("'" ~ ("\\'" | !("'" | NEWLINE) ~ ANY)* ~ "'") }
numeric_literal = @{ "-"? ~ ASCII_DIGIT+ ~ ("." ~ ASCII_DIGIT+)? }
boolean_literal = { "true" | "false" }
null_literal = { "null" }
scalar_literal = _{ quoted_string | numeric_literal | boolean_literal | null_literal }
primitive_type = { "string" | "integer" | "number" | "boolean" | "null" }
array_suffix = { "[]" }
nullable_suffix = { "?" }
type_atom = _{ primitive_type | identifier }
type_reference = { type_atom ~ array_suffix* ~ nullable_suffix? }
enum_predicate = { "enum" ~ whitespace* ~ "(" ~ whitespace* ~ scalar_literal ~ (whitespace* ~ "," ~ whitespace* ~ scalar_literal)* ~ whitespace* ~ ")" }
const_predicate = { "const" ~ whitespace* ~ "(" ~ whitespace* ~ scalar_literal ~ whitespace* ~ ")" }
format_predicate = { "format" ~ whitespace* ~ "(" ~ whitespace* ~ identifier ~ whitespace* ~ ")" }
len_bound = @{ ASCII_DIGIT+ }
len_predicate = { "len" ~ whitespace* ~ "(" ~ whitespace* ~ len_bound? ~ whitespace* ~ ".." ~ whitespace* ~ len_bound? ~ whitespace* ~ ")" }
regex_literal = @{ "/" ~ ("\\/" | !("/" | NEWLINE) ~ ANY)* ~ "/" }
pattern_predicate = { "pattern" ~ whitespace* ~ "(" ~ whitespace* ~ regex_literal ~ whitespace* ~ ")" }
range_predicate = { "range" ~ whitespace* ~ "(" ~ whitespace* ~ numeric_literal? ~ whitespace* ~ ".." ~ whitespace* ~ numeric_literal? ~ whitespace* ~ ")" }
scalar_term = _{ enum_predicate | const_predicate | format_predicate | len_predicate | pattern_predicate | range_predicate | primitive_type | identifier }
scalar_expression = { scalar_term ~ (whitespace* ~ "&" ~ whitespace* ~ scalar_term)* }
scalar_declaration = { "scalar" ~ whitespace+ ~ identifier ~ whitespace* ~ "=" ~ whitespace* ~ scalar_expression }
field_optional = { "?" }
schema_field = { whitespace* ~ identifier ~ field_optional? ~ whitespace* ~ ":" ~ whitespace* ~ type_reference }
schema_object = { "{" ~ NEWLINE* ~ (schema_field ~ NEWLINE*)* ~ whitespace* ~ "}" }
schema_expr_ws = _{ whitespace | NEWLINE }
schema_target = { identifier }
schema_target_list = { schema_target ~ (schema_expr_ws* ~ "," ~ schema_expr_ws* ~ schema_target)+ }
schema_allof_expression = { "allOf" ~ schema_expr_ws* ~ "(" ~ schema_expr_ws* ~ schema_target_list ~ schema_expr_ws* ~ ")" }
schema_oneof_expression = { "oneOf" ~ schema_expr_ws* ~ "(" ~ schema_expr_ws* ~ schema_target_list ~ schema_expr_ws* ~ ")" }
schema_anyof_expression = { "anyOf" ~ schema_expr_ws* ~ "(" ~ schema_expr_ws* ~ schema_target_list ~ schema_expr_ws* ~ ")" }
schema_not_expression = { "not" ~ schema_expr_ws* ~ "(" ~ schema_expr_ws* ~ schema_target ~ schema_expr_ws* ~ ")" }
schema_discriminator_branch = { scalar_literal ~ schema_expr_ws* ~ ":" ~ schema_expr_ws* ~ identifier }
schema_discriminator_expression = {
"discriminator"
~ schema_expr_ws* ~ "(" ~ schema_expr_ws*
~ identifier
~ schema_expr_ws* ~ "," ~ schema_expr_ws*
~ schema_discriminator_branch
~ (schema_expr_ws* ~ "," ~ schema_expr_ws* ~ schema_discriminator_branch)*
~ schema_expr_ws* ~ ")"
}
schema_assignment_expression = _{
schema_discriminator_expression
| schema_allof_expression
| schema_oneof_expression
| schema_anyof_expression
| schema_not_expression
| type_reference
}
schema_object_declaration = { "schema" ~ whitespace+ ~ identifier ~ whitespace* ~ schema_object }
schema_assignment_declaration = { "schema" ~ whitespace+ ~ identifier ~ whitespace* ~ "=" ~ schema_expr_ws* ~ schema_assignment_expression }
declaration = { scalar_declaration | schema_object_declaration | schema_assignment_declaration }
redact_header_directive = { "redact_header" ~ whitespace* ~ "=" ~ whitespace* ~ value }
redact_capture_directive = { "redact_capture" ~ whitespace* ~ "=" ~ whitespace* ~ value }
redact_body_directive = { "redact_body" ~ whitespace* ~ "=" ~ whitespace* ~ value }
preamble = _{ NEWLINE* ~ ((collection_name | collection_description | variable | environment_block | oauth_block | header | query | cookie | callback | timeout_directive | poll_until_directive | poll_every_directive | declaration | redact_header_directive | redact_capture_directive | redact_body_directive) ~ NEWLINE*)+ }
http_method = { "GET" | "PUT" | "POST" | "PATCH" | "DELETE" | "OPTIONS" }
header = { "*" ~ whitespace* ~ key ~ whitespace* ~ "=" ~ whitespace* ~ value }
query = { "?" ~ whitespace* ~ key ~ whitespace* ~ "=" ~ whitespace* ~ value }
protocol_directive = { "protocol" ~ whitespace* ~ "=" ~ whitespace* ~ identifier }
session_directive = { "session" ~ whitespace* ~ "=" ~ whitespace* ~ value }
auth_directive = { "auth" ~ whitespace* ~ "=" ~ whitespace* ~ identifier }
operation_directive = { "operation" ~ whitespace* ~ "=" ~ whitespace* ~ value }
variables_directive = { "variables" ~ whitespace* ~ "=" ~ whitespace* ~ value }
call_directive = { "call" ~ whitespace* ~ "=" ~ whitespace* ~ value }
tool_directive = { "tool" ~ whitespace* ~ "=" ~ whitespace* ~ value }
arguments_directive = { "arguments" ~ whitespace* ~ "=" ~ whitespace* ~ value }
send_directive = { "send" ~ whitespace* ~ "=" ~ whitespace* ~ value }
receive_directive = { "receive" }
within_directive = { "within" ~ whitespace* ~ "=" ~ whitespace* ~ value }
timeout_directive = { "timeout" ~ whitespace* ~ "=" ~ whitespace* ~ value }
poll_until_directive = { "poll_until" ~ whitespace* ~ "=" ~ whitespace* ~ value }
poll_every_directive = { "poll_every" ~ whitespace* ~ "=" ~ whitespace* ~ value }
protocol_version_directive = { "protocol_version" ~ whitespace* ~ "=" ~ whitespace* ~ value }
client_name_directive = { "client_name" ~ whitespace* ~ "=" ~ whitespace* ~ value }
client_version_directive = { "client_version" ~ whitespace* ~ "=" ~ whitespace* ~ value }
capabilities_directive = { "capabilities" ~ whitespace* ~ "=" ~ whitespace* ~ value }
file = { "@" ~ whitespace* ~ value }
text = { value }
form = { "~" ~ whitespace* ~ key ~ whitespace* ~ "=" ~ whitespace* ~ (file | text) }
callback = { "!" ~ whitespace* ~ value }
response_capture = { "&" ~ whitespace* ~ (!NEWLINE ~ ANY)+ }
guard_content = { (!"]" ~ ANY)+ }
guard = _{ "[" ~ guard_content ~ "]" }
guard_prefix = _{ guard ~ whitespace* }
assertion_label = { "^:" ~ whitespace* ~ (!NEWLINE ~ ANY)* }
assertion = { guard_prefix? ~ "^" ~ whitespace* ~ (!NEWLINE ~ ANY)+ }
fragment_path = { (!NEWLINE ~ ANY)+ }
fragment_include = { guard_prefix? ~ "<<" ~ whitespace* ~ fragment_path }
dependency = { ">" ~ whitespace* ~ "requires" ~ whitespace* ~ ":" ~ whitespace* ~ (!NEWLINE ~ ANY)+ }
body_content_type = { value }
body = { (!"~~~" ~ ANY)+ }
body_block = _{ "~~~" ~ whitespace* ~ body_content_type* ~ NEWLINE ~ body* ~ "~~~" }
url = { (!"\n" ~ ANY)+ }
description = { !section_delim ~ !http_method ~ value }
request_target = _{ http_method ~ whitespace+ ~ url }
request_item = _{ variable | dependency | protocol_directive | session_directive | auth_directive | operation_directive | variables_directive | call_directive | tool_directive | arguments_directive | send_directive | receive_directive | within_directive | timeout_directive | poll_until_directive | poll_every_directive | protocol_version_directive | client_name_directive | client_version_directive | capabilities_directive | header | query | cookie | body_block | form | callback | response_capture | assertion_label | assertion | fragment_include | request_target | description }
request = {
request_item ~ (NEWLINE+ ~ request_item)* ~ NEWLINE*
}
requests = {
request ~ (section_delim ~ NEWLINE+ ~ request)*
}
legacy_collection_line = _{ !(request_target | protocol_directive | session_directive | auth_directive | operation_directive | variables_directive | call_directive | tool_directive | arguments_directive | send_directive | receive_directive | within_directive | timeout_directive | poll_until_directive | poll_every_directive | protocol_version_directive | client_name_directive | client_version_directive | capabilities_directive | variable | dependency | header | query | form | callback | response_capture | assertion_label | assertion | fragment_include) ~ !section_delim ~ (!NEWLINE ~ ANY)+ }
legacy_collection_header = _{ legacy_collection_line ~ (NEWLINE+ ~ legacy_collection_line)* ~ NEWLINE* ~ section_delim ~ NEWLINE* }
request_collection_with_preamble = {
preamble ~ section_delim ~ NEWLINE* ~ requests ~ NEWLINE* ~ EOI
}
request_collection_without_preamble = {
legacy_collection_header? ~ (section_delim ~ NEWLINE*)? ~ requests ~ NEWLINE* ~ EOI
}
request_collection_preamble_only = {
preamble ~ NEWLINE* ~ EOI
}
request_collection = {
request_collection_with_preamble | request_collection_without_preamble | request_collection_preamble_only
}