HTTP Methods Reference — Rust source
A searchable reference for every HTTP request method - GET, POST, PUT, PATCH, DELETE, and more. See at a glance which are safe, idempotent, and cacheable, then compare any two methods side by side.
This is the Rust implementation — the same logic the interactive tool runs, in a shareable, citable form.
// Source file: rust.rs
// Language: Rust
//
// HTTP request-method reference — pure, deterministic data + lookups.
//
// CosmoDev polyglot showcase port of the `http-methods` tool, ported from
// src/lib/http-methods.ts. Functionally equivalent to the TypeScript original:
// identical inputs yield identical outputs (case-insensitive lookup, flag +
// free-text filtering, and a human-readable semantic comparison report).
//
// Property flags (safe / idempotent / cacheable / hasBody) follow RFC 9110
// and the MDN reference table.
//
// Display source — part of CosmoDev's polyglot tool pages.
//! HTTP request-method reference — pure data + lookups.
//!
//! The canonical [`METHODS`] table holds the nine RFC 9110 / 9111 methods with
//! their semantic property flags. All helpers are read-only and return
//! borrowed references into that single source of truth.
/// One HTTP request method and its semantic properties.
///
/// Fields use `&'static str` so the canonical table can live as a `const`
/// slice with no allocation.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct MethodEntry {
/// Uppercase method name, e.g. `"GET"`.
pub method: &'static str,
/// Read-only semantics — no server state change.
pub safe: bool,
/// Repeating the call has the same effect as a single call.
pub idempotent: bool,
/// Responses may be stored by a cache (RFC 9110 / MDN).
pub cacheable: bool,
/// The method conventionally carries a request body.
pub has_body: bool,
pub description: &'static str,
pub typical_use: &'static str,
}
/// The nine HTTP request methods (RFC 9110 / 9111), in canonical order.
///
/// `pub const` lets callers treat this as a compile-time constant; the
/// helpers borrow from it via `'static` references.
pub const METHODS: &[MethodEntry] = &[
MethodEntry {
method: "GET",
safe: true,
idempotent: true,
cacheable: true,
has_body: false,
description: "Retrieves a representation of the target resource; a read-only request.",
typical_use: "Fetching a web page, reading an API resource, loading an image.",
},
MethodEntry {
method: "POST",
safe: false,
idempotent: false,
cacheable: true,
has_body: true,
description: "Submits data to be processed, typically creating a new resource or triggering an action.",
typical_use: "Submitting a form, creating a record, publishing a message.",
},
MethodEntry {
method: "PUT",
safe: false,
idempotent: true,
cacheable: false,
has_body: true,
description: "Replaces the target resource entirely with the request body.",
typical_use: "Updating a full record at a known URL, uploading a file by its path.",
},
MethodEntry {
method: "PATCH",
safe: false,
idempotent: false,
cacheable: false,
has_body: true,
description: "Applies a partial modification to the target resource.",
typical_use: "Updating one field of a record, toggling a flag.",
},
MethodEntry {
method: "DELETE",
safe: false,
idempotent: true,
cacheable: false,
has_body: false,
description: "Removes the target resource.",
typical_use: "Deleting a record or file by its URL.",
},
MethodEntry {
method: "HEAD",
safe: true,
idempotent: true,
cacheable: true,
has_body: false,
description: "Identical to GET but returns only the response headers, no body.",
typical_use: "Checking existence, size, or freshness before downloading.",
},
MethodEntry {
method: "OPTIONS",
safe: true,
idempotent: true,
cacheable: false,
has_body: false,
description: "Describes the communication options for the target resource.",
typical_use: "CORS preflight requests, discovering allowed methods.",
},
MethodEntry {
method: "CONNECT",
safe: false,
idempotent: false,
cacheable: false,
has_body: false,
description: "Establishes a tunnel to the server (used with TLS/HTTPS proxies).",
typical_use: "Proxying encrypted connections through an intermediary.",
},
MethodEntry {
method: "TRACE",
safe: true,
idempotent: true,
cacheable: false,
has_body: false,
description: "Performs a message loop-back test along the path to the target (debugging only).",
typical_use: "Diagnosing request transformations by intermediaries.",
},
];
/// Filter options. Each boolean is `Option<bool>` so callers can distinguish
/// "constrain to `false`" (`Some(false)`) from "no constraint" (`None`) — a
/// tri-state a bare `bool` cannot express.
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct MethodFilter {
pub safe: Option<bool>,
pub idempotent: Option<bool>,
pub cacheable: Option<bool>,
/// Free text matched case-insensitively against method, description, and
/// typical_use. Ignored when empty after trimming.
pub query: Option<String>,
}
/// Case-insensitive single-method lookup.
///
/// Returns a static borrow of the canonical entry, or `None` when unknown —
/// the Rust analogue of TS's `MethodEntry | null`.
pub fn get_method(name: &str) -> Option<&'static MethodEntry> {
// ASCII method names: `to_ascii_uppercase` matches TS `toUpperCase` for
// the alphabetic method tokens without paying for full Unicode case-folding.
let n = name.trim().to_ascii_uppercase();
METHODS.iter().find(|m| m.method == n)
}
/// Returns the methods satisfying every present flag and, when `query` is
/// non-empty, matching it in at least one of {method, description, typical_use}.
///
/// Borrows from [`METHODS`] — no allocation of the records themselves, only
/// of the returned `Vec` of references.
pub fn filter_methods(opts: &MethodFilter) -> Vec<&'static MethodEntry> {
let q = opts
.query
.as_deref()
.map(|q| q.trim().to_ascii_lowercase())
.unwrap_or_default();
METHODS
.iter()
.filter(|m| {
// Each present flag acts as an AND constraint; `None` means skip.
if let Some(want) = opts.safe {
if m.safe != want {
return false;
}
}
if let Some(want) = opts.idempotent {
if m.idempotent != want {
return false;
}
}
if let Some(want) = opts.cacheable {
if m.cacheable != want {
return false;
}
}
if q.is_empty() {
return true;
}
m.method.to_ascii_lowercase().contains(&q)
|| m.description.to_ascii_lowercase().contains(&q)
|| m.typical_use.to_ascii_lowercase().contains(&q)
})
.collect()
}
/// Semantic diff between two methods.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct MethodComparison {
/// Both methods share the `safe` flag.
pub same_safety: bool,
/// Both methods share the `idempotent` flag.
pub same_idempotence: bool,
/// One sentence per mismatched property (safe, idempotent, cacheable, has_body).
pub differences: Vec<String>,
}
/// Surfaces where two methods' semantics agree and differ.
///
/// `differences` lists every mismatched property as a human-readable sentence,
/// reproducing the canonical phrasing verbatim so output stays identical to
/// the TypeScript original and the other polyglot ports.
pub fn compare_methods(a: &MethodEntry, b: &MethodEntry) -> MethodComparison {
let mut differences = Vec::new();
if a.safe != b.safe {
differences.push(format!(
"{} is {}, {} is {}.",
a.method,
safe_word(a.safe),
b.method,
safe_word(b.safe),
));
}
if a.idempotent != b.idempotent {
differences.push(format!(
"{} is {}, {} is {}.",
a.method,
idempotent_word(a.idempotent),
b.method,
idempotent_word(b.idempotent),
));
}
if a.cacheable != b.cacheable {
differences.push(format!(
"{} is {}, {} is {}.",
a.method,
cacheable_word(a.cacheable),
b.method,
cacheable_word(b.cacheable),
));
}
if a.has_body != b.has_body {
differences.push(format!(
"{} {}, {} {}.",
a.method,
body_word(a.has_body),
b.method,
body_word(b.has_body),
));
}
MethodComparison {
same_safety: a.safe == b.safe,
same_idempotence: a.idempotent == b.idempotent,
differences,
}
}
// Phrasing helpers keep the difference-sentence wording in one place, so the
// output stays in lock-step across every polyglot port.
fn safe_word(v: bool) -> &'static str {
if v { "safe" } else { "not safe" }
}
fn idempotent_word(v: bool) -> &'static str {
if v { "idempotent" } else { "not idempotent" }
}
fn cacheable_word(v: bool) -> &'static str {
if v { "cacheable" } else { "not cacheable" }
}
fn body_word(v: bool) -> &'static str {
if v { "takes a body" } else { "does not take a body" }
}
Also available in 13 other languages
Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →