From 37196caf751dc62987977bc8ecd704f232242f52 Mon Sep 17 00:00:00 2001 From: DarkCat09 Date: Thu, 8 Aug 2024 16:24:01 +0400 Subject: [PATCH] docs: add doc-comments to client::response --- src/client/response.rs | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/client/response.rs b/src/client/response.rs index a3e6cff..56f4632 100644 --- a/src/client/response.rs +++ b/src/client/response.rs @@ -1,3 +1,5 @@ +//! Client-side response structure + use crate::{status::Status, LibError, ReplyType}; use bytes::Bytes; @@ -5,6 +7,8 @@ use tokio::io::AsyncReadExt; type BodyStream = tokio::io::BufReader>; +/// Client-side response structure wrapping a [`Status`], +/// a metadata string and a TLS stream #[derive(Debug)] pub struct Response { status: Status, @@ -21,11 +25,25 @@ impl Response { } } + /// Check if status code is 2x (success). #[inline] pub fn is_ok(&self) -> bool { self.status.reply_type() == ReplyType::Success } + /// Return `Ok(self)` if status code is 2x, otherwise `Err(self)`. + /// + /// # Examples + /// ``` + /// match client.request("gemini://dc09.ru").await?.ensure_ok() { + /// Ok(resp) => { + /// println!("{}", resp.text().await?); + /// } + /// Err(resp) => { + /// println!("{}", resp.message()); + /// } + /// } + /// ``` pub fn ensure_ok(self) -> Result { if self.status.reply_type() == ReplyType::Success { Ok(self) @@ -34,28 +52,49 @@ impl Response { } } + /// Get the response status code as [`Status`]. pub fn status(&self) -> Status { self.status } + /// Get the response metadata -- the text after a status code + space. + /// - In 1x responses (input), it contains an input prompt message. + /// - In 2x responses (success), it contains a MIME type of the body. + /// - In 3x responses (redirect), it contains a URL. + /// - In 4x, 5x (fail), 6x (auth), it contains an error message. pub fn message(&self) -> &str { &self.message } + /// Get the response body MIME type by parsing the metadata field. + /// If you call this method on a non-2x response, you'll get a parse error. + /// It's strongly recommended to check the status code first + /// (most handy is [`Response::is_ok()`]). pub fn mime(&self) -> Result { self.message.parse().map_err(LibError::InvalidMime) } + /// Borrow the wrapped TLS stream as `&mut`. + /// + /// # Reminder + /// You can read data from one stream only once, + /// so calling `.bytes()` after `.stream().read_to_end(…)` + /// (or `.bytes()` twice, or `.text()` after `.bytes()` and vice versa) + /// on the same response will result in empty output. pub fn stream(&mut self) -> &mut BodyStream { &mut self.stream } + /// Read the whole response body and return as [`Bytes`]. + /// See also [the note](#reminder) to `stream()`. pub async fn bytes(&mut self) -> Result { let mut buf = Vec::new(); self.stream.read_to_end(&mut buf).await?; Ok(Bytes::from(buf)) } + /// Read the whole response body as a UTF-8 [`String`]. + /// See also [the note](#reminder) to `stream()`. pub async fn text(&mut self) -> Result { let mut buf = String::new(); self.stream.read_to_string(&mut buf).await?;