/
nv-lang
/
nova-http
Обзор
Документация
Войти
/
nv-lang
/
nova-http
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
main
src/method.nv
105 строк
4 KB
Evgeniy Golovin
refactor(179-conv-chains, [222 №79]): А-конверсии — consume-голое-имя и static→метод-на-источнике (определения)
25 июл 2026, 00:36
25 июл 2026, 00:36
2af035e
Код
Авторство
О чём код?
// SPDX-License-Identifier: MIT OR Apache-2.0 // nova-http: method.nv — HTTP-метод (D358). Extracted from monorepo // std/http (Plan 203 Ф.1). // // Стандартные методы — варианты-константы; нестандартные (RFC 7231 §4.1 // extension-method, напр. "PROPFIND") — `Other(str)` с УЖЕ-провалидированным // tchar-токеном (сконструировать минуя `parse` нельзя — фабрика). Сравнение // case-sensitive (метод регистрозависим, RFC 7230 §3.1.1). Бьёт Go (`string`, // опечатка компилится). module http /// HTTP-метод (RFC 7231 §4). `@is_idempotent` — load-bearing для retry-policy. #stable(since = "0.1") export type Method enum | Get | Head | Post | Put | Delete | Connect | Options | Trace | Patch | Other(str) // валидированный tchar-токен (uppercase-конвенция) /// Разобрать/валидировать метод-токен. Пустой / не-token → `Protocol`. /// /// Известные методы отображаются в константу-вариант; прочий валидный tchar-токен /// → `Other`. /// /// # Examples /// ```nova /// assert("GET".to_method()!! == Method.Get) /// assert("PROPFIND".to_method()!! == Method.Other("PROPFIND")) /// ``` #stable(since = "0.1") export fn str @to_method() -> Result[Method, HttpError] { if @byte_len() == 0 { return Err(HttpError.protocol_error("empty method token")) } for c in @chars() { if !is_tchar(c) { return Err(HttpError.protocol_error("invalid method token")) } } Ok(match @ { "GET" => Get "HEAD" => Head "POST" => Post "PUT" => Put "DELETE" => Delete "CONNECT" => Connect "OPTIONS" => Options "TRACE" => Trace "PATCH" => Patch _ => Other(@) }) } /// Токен метода на проводе. `Other` → as-is. #stable(since = "0.1") export fn Method @str() -> str { match @ { Get => "GET" Head => "HEAD" Post => "POST" Put => "PUT" Delete => "DELETE" Connect => "CONNECT" Options => "OPTIONS" Trace => "TRACE" Patch => "PATCH" Other(s) => s } } /// Safe-метод (RFC 7231 §4.2.1): GET/HEAD/OPTIONS/TRACE — без side-effects. #stable(since = "0.1") export fn Method @is_safe() -> bool { match @ { Get | Head | Options | Trace => true _ => false } } /// Идемпотентный метод (RFC 7231 §4.2.2): safe + PUT/DELETE. Load-bearing для /// auto-retry (только идемпотентные реплеятся, Q16). #stable(since = "0.1") export fn Method @is_idempotent() -> bool { match @ { Put | Delete => true _ => @is_safe() } } /// По умолчанию несёт тело запроса (POST/PUT/PATCH). GET/HEAD/DELETE — нет. #stable(since = "0.1") export fn Method @allows_body() -> bool { match @ { Post | Put | Patch => true Other(_) => true _ => false } } // RFC 7230 §3.2.6 tchar: "!#$%&'*+-.^_`|~" / DIGIT / ALPHA. fn is_tchar(c char) -> bool { if c.is_ascii_alphanumeric() { return true } c == '!' || c == '#' || c == '$' || c == '%' || c == '&' || c == '\'' || c == '*' || c == '+' || c == '-' || c == '.' || c == '^' || c == '_' || c == '`' || c == '|' || c == '~' }