/
nv-lang
/
nova-http
Обзор
Документация
Войти
/
nv-lang
/
nova-http
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
main
src/response_ext.nv
69 строк
3 KB
Evgeniy Golovin
style(225.1): вертикальный ритм — sweep классов a/b/e (src)
26 июл 2026, 02:21
26 июл 2026, 02:21
d0e6b36
Код
Авторство
О чём код?
// SPDX-License-Identifier: MIT OR Apache-2.0 // nova-http: response_ext.nv — client-facing Response methods (D360). // Extracted from monorepo std/http (Plan 203 Ф.1). // // Adds reqwest-style conveniences on top of the Ф.1 must-consume `Response` // (message.nv): borrow accessors (`@header`/`@content_length`/`@cookies`) and the // consuming terminal `@error_for_status` (opt-in non-2xx→Err). 4xx/5xx stay a // VALID Response — the only path to a `Status` error is `@error_for_status()` (Q4). // // Dynamic `Response @json() -> JsonValue` lives in `http.client` (keeps the // std/encoding/json dependency out of the lean core message-model module). Typed // `@json[T]()` (serde) gates on Plan 180 Ф.4 [M-178-typed-json-needs-180]. module http /// First value of `name` as a string (case-insensitive), or `None`. #stable(since = "0.1") export fn Response @header(name str) -> Option[str] { match @headers.get(name) { Some(hv) => match hv.to_str() { Ok(s) => Some(s), Err(_) => None } None => None } } /// Parsed `Content-Length`, or `None` (also `None` on conflict — see full parse /// via `@headers().content_length()`). #stable(since = "0.1") export fn Response @content_length() -> Option[int] { match @headers.content_length() { Ok(o) => o Err(_) => None } } /// Parsed `Set-Cookie` response headers (RFC 6265bis). #stable(since = "0.1") export fn Response @cookies() -> []SetCookie { mut out = []SetCookie.new() for hv in @headers.get_all("set-cookie") { match hv.to_str() { Ok(s) => match s.to_setcookie() { Ok(sc) => { out.push(sc); () } Err(_) => () // [M-lint-findings-result-discarded-lenient-parse] } Err(_) => () // [M-lint-findings-result-discarded-lenient-parse] } } out } /// reqwest opt-in: non-2xx/3xx → `Err(Status(code))`, else `Ok(self)`. /// /// CONSUMES self: the body is materialized (CORE buffers it in memory) and the /// Response is rebuilt on the success path. On the error path the error-body is /// drained (must-consume preserved); the "keep error body" variant is a followup. /// [M-178-error-for-status-drops-body] #stable(since = "0.1") export fn Response consume @error_for_status() -> Result[Response, HttpError] { ro ver = @version ro st = @status ro hdrs = @headers ro ok = st.is_success() || st.is_redirect() ro body = @into_bytes()? if ok { Ok(Response.new(ver, st, hdrs, body)) } else { Err(HttpError.new(Status(st))) } }