diff --git a/crates/rubedo-macros/src/lib.rs b/crates/rubedo-macros/src/lib.rs index 085a1f8..a65ac41 100644 --- a/crates/rubedo-macros/src/lib.rs +++ b/crates/rubedo-macros/src/lib.rs @@ -32,7 +32,7 @@ use std::net::IpAddr; /// /// Note that this macro will panic if it fails to parse a string literal as an /// IP address. This is by design, so that all variants of IP creation return an -/// `IpAddr` instance, just like [`IpAddr::from()`]. This macro is intended to +/// [`IpAddr`] instance, just like [`IpAddr::from()`]. This macro is intended to /// be used with hard-coded addresses. If you need to handle errors, use the /// standard [`IpAddr::from_str()`](IpAddr) method instead. /// @@ -47,7 +47,7 @@ use std::net::IpAddr; /// assert_eq!(ip!(1, 2, 3, 4), IpAddr::from([1, 2, 3, 4])); /// ``` /// -/// # See Also +/// # See also /// /// * [`IpAddr`] /// diff --git a/crates/rubedo/src/chrono.rs b/crates/rubedo/src/chrono.rs index 9f37196..4c5d4c2 100644 --- a/crates/rubedo/src/chrono.rs +++ b/crates/rubedo/src/chrono.rs @@ -34,11 +34,12 @@ pub trait DurationExt { ]; // humanize - /// Returns a human-readable string representation of the duration. + /// Returns a human-readable string representation of a [`Duration`]. /// - /// This will indicate the duration as an expression of the largest unit + /// This will indicate the [`Duration`] as an expression of the largest unit /// available. For example, if the duration is 1 year, 2 months, 3 weeks, /// 4 days, 5 hours, 6 minutes, and 7 seconds, it will return "1 year". + /// fn humanize(&self) -> String; } @@ -64,6 +65,7 @@ pub trait NaiveDateExt { /// /// Although this is a static method, it does not return an [`Option`] as it /// cannot fail. + /// fn today() -> NaiveDate; // days_in_month @@ -71,6 +73,12 @@ pub trait NaiveDateExt { /// /// This method operates on `&self`. For the equivalent method that operates /// without an instance, see [`days_in_month_opt()`](NaiveDateExt::days_in_month_opt()). + /// + /// # See also + /// + /// * [`days_in_month_opt()`](NaiveDateExt::days_in_month_opt()) + /// * [`days_in_year()`](NaiveDateExt::days_in_year()) + /// fn days_in_month(&self) -> u32; // days_in_month_opt @@ -80,7 +88,13 @@ pub trait NaiveDateExt { /// operates on `&self`, see [`days_in_month()`](NaiveDateExt::days_in_month()). /// /// The outcome is wrapped in an [`Option`]. If the given year or month is - /// invalid, `None` is returned. + /// invalid, [`None`] is returned. + /// + /// # See also + /// + /// * [`days_in_month()`](NaiveDateExt::days_in_month()) + /// * [`days_in_year_opt()`](NaiveDateExt::days_in_year_opt()) + /// fn days_in_month_opt(year: i32, month: u32) -> Option; // days_in_year @@ -88,6 +102,12 @@ pub trait NaiveDateExt { /// /// This method operates on `&self`. For the equivalent method that operates /// without an instance, see [`days_in_year_opt()`](NaiveDateExt::days_in_year_opt()). + /// + /// # See also + /// + /// * [`days_in_month()`](NaiveDateExt::days_in_month()) + /// * [`days_in_year_opt()`](NaiveDateExt::days_in_year_opt()) + /// fn days_in_year(&self) -> u32; // days_in_year_opt @@ -97,7 +117,13 @@ pub trait NaiveDateExt { /// operates on `&self`, see [`days_in_year()`](NaiveDateExt::days_in_year()). /// /// The outcome is wrapped in an [`Option`]. If the given year is invalid, - /// `None` is returned. + /// [`None`] is returned. + /// + /// # See also + /// + /// * [`days_in_month_opt()`](NaiveDateExt::days_in_month_opt()) + /// * [`days_in_year()`](NaiveDateExt::days_in_year()) + /// fn days_in_year_opt(year: i32) -> Option; // is_leap_year @@ -105,6 +131,11 @@ pub trait NaiveDateExt { /// /// This method operates on `&self`. For the equivalent method that operates /// without an instance, see [`is_leap_year_opt()`](NaiveDateExt::is_leap_year_opt()). + /// + /// # See also + /// + /// * [`is_leap_year_opt()`](NaiveDateExt::is_leap_year_opt()) + /// fn is_leap_year(&self) -> bool; // is_leap_year_opt @@ -114,7 +145,12 @@ pub trait NaiveDateExt { /// operates on `&self`, see [`is_leap_year()`](NaiveDateExt::is_leap_year()). /// /// The outcome is wrapped in an [`Option`]. If the given year is invalid, - /// `None` is returned. + /// [`None`] is returned. + /// + /// # See also + /// + /// * [`is_leap_year()`](NaiveDateExt::is_leap_year()) + /// fn is_leap_year_opt(year: i32) -> Option; // start_of_month @@ -122,6 +158,14 @@ pub trait NaiveDateExt { /// /// This method operates on `&self`. For the equivalent method that operates /// without an instance, see [`start_of_month_opt()`](NaiveDateExt::start_of_month_opt()). + /// + /// # See also + /// + /// * [`end_of_month()`](NaiveDateExt::end_of_month()) + /// * [`end_of_year()`](NaiveDateExt::end_of_year()) + /// * [`start_of_month_opt()`](NaiveDateExt::start_of_month_opt()) + /// * [`start_of_year()`](NaiveDateExt::start_of_year()) + /// fn start_of_month(&self) -> NaiveDate; // start_of_month_opt @@ -131,7 +175,15 @@ pub trait NaiveDateExt { /// operates on `&self`, see [`start_of_month()`](NaiveDateExt::start_of_month()). /// /// The outcome is wrapped in an [`Option`]. If the given year or month is - /// invalid, `None` is returned. + /// invalid, [`None`] is returned. + /// + /// # See also + /// + /// * [`end_of_month_opt()`](NaiveDateExt::end_of_month_opt()) + /// * [`end_of_year_opt()`](NaiveDateExt::end_of_year_opt()) + /// * [`start_of_month()`](NaiveDateExt::start_of_month()) + /// * [`start_of_year_opt()`](NaiveDateExt::start_of_year_opt()) + /// fn start_of_month_opt(year: i32, month: u32) -> Option; // end_of_month @@ -139,6 +191,14 @@ pub trait NaiveDateExt { /// /// This method operates on `&self`. For the equivalent method that operates /// without an instance, see [`end_of_month_opt()`](NaiveDateExt::end_of_month_opt()). + /// + /// # See also + /// + /// * [`end_of_month_opt()`](NaiveDateExt::end_of_month_opt()) + /// * [`end_of_year()`](NaiveDateExt::end_of_year()) + /// * [`start_of_month()`](NaiveDateExt::start_of_month()) + /// * [`start_of_year()`](NaiveDateExt::start_of_year()) + /// fn end_of_month(&self) -> NaiveDate; // end_of_month_opt @@ -148,7 +208,15 @@ pub trait NaiveDateExt { /// operates on `&self`, see [`end_of_month()`](NaiveDateExt::end_of_month()). /// /// The outcome is wrapped in an [`Option`]. If the given year or month is - /// invalid, `None` is returned. + /// invalid, [`None`] is returned. + /// + /// # See also + /// + /// * [`end_of_month()`](NaiveDateExt::end_of_month()) + /// * [`end_of_year_opt()`](NaiveDateExt::end_of_year_opt()) + /// * [`start_of_month_opt()`](NaiveDateExt::start_of_month_opt()) + /// * [`start_of_year_opt()`](NaiveDateExt::start_of_year_opt()) + /// fn end_of_month_opt(year: i32, month: u32) -> Option; // start_of_year @@ -156,6 +224,14 @@ pub trait NaiveDateExt { /// /// This method operates on `&self`. For the equivalent method that operates /// without an instance, see [`start_of_year_opt()`](NaiveDateExt::start_of_year_opt()). + /// + /// # See also + /// + /// * [`end_of_month()`](NaiveDateExt::end_of_month()) + /// * [`end_of_year()`](NaiveDateExt::end_of_year()) + /// * [`start_of_month()`](NaiveDateExt::start_of_month()) + /// * [`start_of_year_opt()`](NaiveDateExt::start_of_year_opt()) + /// fn start_of_year(&self) -> NaiveDate; // start_of_year_opt @@ -165,7 +241,15 @@ pub trait NaiveDateExt { /// operates on `&self`, see [`start_of_year()`](NaiveDateExt::start_of_year()). /// /// The outcome is wrapped in an [`Option`]. If the given year is invalid, - /// `None` is returned. + /// [`None`] is returned. + /// + /// # See also + /// + /// * [`end_of_month_opt()`](NaiveDateExt::end_of_month_opt()) + /// * [`end_of_year_opt()`](NaiveDateExt::end_of_year_opt()) + /// * [`start_of_month_opt()`](NaiveDateExt::start_of_month_opt()) + /// * [`start_of_year()`](NaiveDateExt::start_of_year()) + /// fn start_of_year_opt(year: i32) -> Option; // end_of_year @@ -173,6 +257,14 @@ pub trait NaiveDateExt { /// /// This method operates on `&self`. For the equivalent method that operates /// without an instance, see [`end_of_year_opt()`](NaiveDateExt::end_of_year_opt()). + /// + /// # See also + /// + /// * [`end_of_month()`](NaiveDateExt::end_of_month()) + /// * [`end_of_year_opt()`](NaiveDateExt::end_of_year_opt()) + /// * [`start_of_month()`](NaiveDateExt::start_of_month()) + /// * [`start_of_year()`](NaiveDateExt::start_of_year()) + /// fn end_of_year(&self) -> NaiveDate; // end_of_year_opt @@ -182,7 +274,15 @@ pub trait NaiveDateExt { /// operates on `&self`, see [`end_of_year()`](NaiveDateExt::end_of_year()). /// /// The outcome is wrapped in an [`Option`]. If the given year is invalid, - /// `None` is returned. + /// [`None`] is returned. + /// + /// # See also + /// + /// * [`end_of_month_opt()`](NaiveDateExt::end_of_month_opt()) + /// * [`end_of_year()`](NaiveDateExt::end_of_year()) + /// * [`start_of_month_opt()`](NaiveDateExt::start_of_month_opt()) + /// * [`start_of_year_opt()`](NaiveDateExt::start_of_year_opt()) + /// fn end_of_year_opt(year: i32) -> Option; } diff --git a/crates/rubedo/src/http.rs b/crates/rubedo/src/http.rs index 54545d6..8d1f60f 100644 --- a/crates/rubedo/src/http.rs +++ b/crates/rubedo/src/http.rs @@ -57,6 +57,7 @@ pub enum ContentType { /// [`String`] when serialised. #[default] Text, + /// The response body is binary. It will be represented as a [`String`] /// in base64 format when serialised. Binary, @@ -105,12 +106,12 @@ impl Error for ResponseError {} /// whether the data is binary or text. If [`Text`](ContentType::Text), then the /// conversion uses [`from_utf8_lossy()`](String::from_utf8_lossy()), so no /// errors will occur, but if the body is not valid UTF8 then the resulting -/// `String` will not be exactly the same. If an accurate representation of the -/// body is required then it should be set to [`Binary`](ContentType::Binary), +/// [`String`] will not be exactly the same. If an accurate representation of +/// the body is required then it should be set to [`Binary`](ContentType::Binary), /// or else it should be extracted and converted to a `Vec` and then run -/// through the `Debug` or `Display` formatters directly. +/// through the [`Debug`] or [`Display`] formatters directly. /// -/// # See Also +/// # See also /// /// * [`axum::response`] /// * [`axum::response::Response`] @@ -135,6 +136,7 @@ pub struct UnpackedResponse { /// in serialised form such as JSON. #[serde(serialize_with = "serialize_status_code", deserialize_with = "deserialize_status_code")] pub status: StatusCode, + /// The response headers. These are in a vector rather than a hashmap /// because there may be multiple headers with the same name. They are /// sorted by name, and then by value, allowing for reliable comparison. @@ -142,11 +144,12 @@ pub struct UnpackedResponse { /// only very rarely matter, even when logging, and sorting allows /// duplicates to be spotted by eye more easily in logs. pub headers: Vec, + /// The response body. This originates from the response body as a [`Bytes`] /// container, but gets stored here as a vector of bytes for convenience. /// This may not be valid UTF8, so is not converted to a [`String`]. That /// step is left as optional for the caller, if required (and happens when - /// running the `UnpackedResponse` struct through the [`Debug`] or + /// running the [`UnpackedResponse`] struct through the [`Debug`] or /// [`Display`] formatters). pub body: UnpackedResponseBody, } @@ -165,7 +168,7 @@ impl PartialEq for UnpackedResponse { /// purpose of this struct is to formalise the data structure used by /// [`UnpackedResponse`] for storing headers. /// -/// # See Also +/// # See also /// /// * [`UnpackedResponse`] /// @@ -174,6 +177,7 @@ pub struct UnpackedResponseHeader { // Public properties /// The response header name. pub name: String, + /// The response header value. pub value: String, } @@ -198,17 +202,17 @@ impl PartialEq for UnpackedResponseHeader { /// the caller, if required (and happens when running through the [`Debug`] or /// [`Display`] formatters). /// -/// The conversion to a `String` when run through the `Debug` and `Display` -/// formatters is because human-readable output is the intuitively-expected -/// outcome in this situation. The behaviour can be controlled with the -/// [`ContentType`] enum, which is used to determine whether the data is binary -/// or text. If [`Text`](ContentType::Text), then the conversion uses -/// [`from_utf8_lossy()`](String::from_utf8_lossy()), so no errors will occur, -/// but if the body is not valid UTF8 then the resulting `String` will not be -/// exactly the same. If an accurate representation of the body is required then -/// it should be set to [`Binary`](ContentType::Binary), or else it should be -/// extracted and converted to a `Vec` and then run through the `Debug` or -/// `Display` formatters directly. +/// The conversion to a [`String`] when run through the [`Debug`] and +/// [`Display`] formatters is because human-readable output is the +/// intuitively-expected outcome in this situation. The behaviour can be +/// controlled with the [`ContentType`] enum, which is used to determine whether +/// the data is binary or text. If [`Text`](ContentType::Text), then the +/// conversion uses [`from_utf8_lossy()`](String::from_utf8_lossy()), so no +/// errors will occur, but if the body is not valid UTF8 then the resulting +/// [`String`] will not be exactly the same. If an accurate representation of +/// the body is required then it should be set to [`Binary`](ContentType::Binary), +/// or else it should be extracted and converted to a `Vec` and then run +/// through the [`Debug`] or [`Display`] formatters directly. /// /// This struct is very similar in nature to the standard Rust [`String`] /// struct, in that it is a wrapper around a vector of bytes, and so its design @@ -217,18 +221,19 @@ impl PartialEq for UnpackedResponseHeader { /// struct rather than a regular struct. /// /// Note that serialisation/deserialisation of this struct directly will produce -/// and expect a `String`, not a vector of bytes. This is because this is the +/// and expect a [`String`], not a vector of bytes. This is because this is the /// most useful and fitting behaviour for the intended purpose, as with the -/// implementations of `Display` and [`FromStr`]. As noted above, this is lossy -/// if the `ContentType` is `Text` and the data is not valid UTF8, but not if -/// set to `Binary`. +/// implementations of [`Display`] and [`FromStr`]. As noted above, this is +/// lossy if the [`ContentType`] is [`Text`](ContentType::Text) and the data is +/// not valid UTF8, but not if set to [`Binary`](ContentType::Binary). /// -/// # See Also +/// # See also /// /// * [`UnpackedResponse`] /// #[derive(Default)] pub struct UnpackedResponseBody { + // Private properties /// The response body as a vector of bytes. The data originates from the /// response body as a [`Bytes`] container, but gets stored here as a vector /// of bytes for convenience. This may not be valid UTF8, so is not @@ -236,6 +241,7 @@ pub struct UnpackedResponseBody { /// if required (and happens when running through the [`Debug`] or /// [`Display`] formatters). body: Vec, + /// The content type of the response body. This is used to determine how to /// represent and interpret the response body when performing serialisation /// and deserialisation, including for display. The default content type is @@ -259,7 +265,7 @@ impl UnpackedResponseBody { // content_type /// Returns the content type of the response body. /// - /// # See Also + /// # See also /// /// * [`ContentType`] /// * [`UnpackedResponseBody::is_binary()`] @@ -276,7 +282,7 @@ impl UnpackedResponseBody { /// This method is chainable, as it returns a mutable reference to the /// response body instance. /// - /// # See Also + /// # See also /// /// * [`ContentType`] /// * [`UnpackedResponseBody::content_type()`] @@ -289,7 +295,7 @@ impl UnpackedResponseBody { // is_binary /// Returns whether the response body is binary. /// - /// # See Also + /// # See also /// /// * [`ContentType`] /// * [`UnpackedResponseBody::content_type()`] @@ -302,7 +308,7 @@ impl UnpackedResponseBody { // is_text /// Returns whether the response body is text. /// - /// # See Also + /// # See also /// /// * [`ContentType`] /// * [`UnpackedResponseBody::content_type()`] @@ -335,7 +341,7 @@ impl UnpackedResponseBody { /// non-destructive, read-only manner while keeping the original response /// body intact. /// - /// # See Also + /// # See also /// /// * [`UnpackedResponseBody::as_mut_bytes()`] /// * [`UnpackedResponseBody::into_bytes()`] @@ -371,14 +377,14 @@ impl UnpackedResponseBody { /// /// Note also that a better name for this method could be `as_mut_vec()`, /// which would be consistent with the standard library's - /// `String::as_mut_vec()` method, which this method is modelled after, but - /// that would break consistency with the other methods on this struct. In - /// addition, there is another method called [`str::as_bytes_mut()`], which - /// appears to be named quite inconsistently with other comparable methods, - /// and so calling this method `as_mut_bytes()` might cause confusion, but - /// is at least self-consistent. + /// [`String::as_mut_vec()`] method, which this method is modelled after, + /// but that would break consistency with the other methods on this struct. + /// In addition, there is another method called [`str::as_bytes_mut()`], + /// which appears to be named quite inconsistently with other comparable + /// methods, and so calling this method `as_mut_bytes()` might cause + /// confusion, but is at least self-consistent. /// - /// # See Also + /// # See also /// /// * [`UnpackedResponseBody::as_bytes()`] /// * [`UnpackedResponseBody::into_bytes()`] @@ -415,7 +421,7 @@ impl UnpackedResponseBody { /// would be inconsistent with the standard library's /// [`String::into_bytes()`] method, which this method is modelled after. /// - /// # See Also + /// # See also /// /// * [`UnpackedResponseBody::as_bytes()`] /// * [`UnpackedResponseBody::as_mut_bytes()`] @@ -436,7 +442,7 @@ impl UnpackedResponseBody { /// in future, so "conversion" is implied and expected as a theoretical /// behaviour.) Ownership of the cloned and converted byte data is /// transferred to the caller, and there are no side effects on the internal - /// state of the `UnpackedResponseBody` instance. + /// state of the [`UnpackedResponseBody`] instance. /// /// - This method returns a `Vec` vector of bytes without consuming /// the response body contents. @@ -455,7 +461,7 @@ impl UnpackedResponseBody { /// would be inconsistent with the standard library's /// [`String::into_bytes()`] method. /// - /// # See Also + /// # See also /// /// * [`UnpackedResponseBody::as_bytes()`] /// * [`UnpackedResponseBody::as_mut_bytes()`] @@ -470,10 +476,10 @@ impl UnpackedResponseBody { /// /// This does not consume the response body, but clones it, as is necessary /// to perform the conversion to base64. It converts straight from bytes to - /// base64, without converting to a `String` first, because the response + /// base64, without converting to a [`String`] first, because the response /// body is binary data. /// - /// # See Also + /// # See also /// /// * [`UnpackedResponseBody::from_base64()`] /// @@ -486,14 +492,14 @@ impl UnpackedResponseBody { /// /// This method does not consume the input string, but clones it, as is /// necessary to perform the conversion from [`base64`]. It converts - /// straight from base64 to bytes, without converting to a `String` first, + /// straight from base64 to bytes, without converting to a [`String`] first, /// because the response body is binary data. This means that no UTF8 /// validation is performed. /// /// Note that unlike the [`From`] type conversion implementations, this - /// returns a `Result`. + /// returns a [`Result`]. /// - /// # See Also + /// # See also /// /// * [`UnpackedResponseBody::to_base64()`] /// @@ -552,15 +558,15 @@ impl UnpackedResponseBody { /// data. The response body is not required to be valid UTF8, so this method /// does not check the validity of the byte before appending it. /// - /// This method accepts a [`u8`] instead of a [`char`] because a `char` - /// represents a single Unicode scalar value. In Rust, a `char` is always 4 - /// bytes long because it can represent any Unicode scalar value, including - /// those outside the Basic Multilingual Plane. If `push()` accepted a - /// `char`, it would be signaling that `UnpackedResponseBody` is - /// Unicode-aware and can handle any Unicode character - which is not the - /// case. A `u8`, on the other hand, represents a single byte. By having - /// `push()` accept a `u8`, it's signaling that `UnpackedResponseBody` is - /// byte-oriented. A specific [`push_char()`](UnpackedResponseBody::push_char()) + /// This method accepts a [`u8`] instead of a [`char`] because a [`char`] + /// represents a single Unicode scalar value. In Rust, a [`char`] is always + /// 4 bytes long because it can represent any Unicode scalar value, + /// including those outside the Basic Multilingual Plane. If `push()` + /// accepted a [`char`], it would be signaling that [`UnpackedResponseBody`] + /// is Unicode-aware and can handle any Unicode character - which is not the + /// case. A [`u8`], on the other hand, represents a single byte. By having + /// `push()` accept a [`u8`], it's signaling that [`UnpackedResponseBody`] + /// is byte-oriented. A specific [`push_char()`](UnpackedResponseBody::push_char()) /// method is also available, but `push()` is the most general method for /// appending bytes to the response body. /// @@ -568,7 +574,7 @@ impl UnpackedResponseBody { /// /// * `byte` - The byte to append to the response body. /// - /// # See Also + /// # See also /// /// * [`UnpackedResponseBody::push_bytes()`] /// * [`UnpackedResponseBody::push_char()`] @@ -590,7 +596,7 @@ impl UnpackedResponseBody { /// /// * `bytes` - The byte slice to append to the response body. /// - /// # See Also + /// # See also /// /// * [`UnpackedResponseBody::push()`] /// * [`UnpackedResponseBody::push_char()`] @@ -603,15 +609,15 @@ impl UnpackedResponseBody { // push_char /// Appends a [`char`] to the response body. /// - /// Appends a given character onto the end of the response body. The `char` - /// is converted to bytes and then appended to the end of the response - /// body's existing byte data. + /// Appends a given character onto the end of the response body. The + /// [`char`] is converted to bytes and then appended to the end of the + /// response body's existing byte data. /// /// # Parameters /// - /// * `char` - The `char` to append to the response body. + /// * `char` - The [`char`] to append to the response body. /// - /// # See Also + /// # See also /// /// * [`UnpackedResponseBody::push()`] /// * [`UnpackedResponseBody::push_bytes()`] @@ -634,7 +640,7 @@ impl UnpackedResponseBody { /// /// * `string` - The string slice to append to the response body. /// - /// # See Also + /// # See also /// /// * [`UnpackedResponseBody::push()`] /// * [`UnpackedResponseBody::push_char()`] @@ -649,7 +655,8 @@ impl Add<&[u8]> for UnpackedResponseBody { type Output = Self; // add - /// Adds a `&[u8]` to an [`UnpackedResponseBody`]. + /// Adds a [`&[u8]`](https://doc.rust-lang.org/std/primitive.slice.html) to + /// an [`UnpackedResponseBody`]. fn add(mut self, other: &[u8]) -> Self { self.push_bytes(other); self @@ -660,7 +667,8 @@ impl Add<&[u8; N]> for UnpackedResponseBody { type Output = Self; // add - /// Adds a `&[u8; N]` to an [`UnpackedResponseBody`]. + /// Adds a [`&[u8; N]`](https://doc.rust-lang.org/std/primitive.slice.html) + /// to an [`UnpackedResponseBody`]. fn add(mut self, other: &[u8; N]) -> Self { self.push_bytes(other); self @@ -682,7 +690,7 @@ impl Add<&char> for UnpackedResponseBody { type Output = Self; // add - /// Adds a `&char` to an [`UnpackedResponseBody`]. + /// Adds a [`&char`](char) to an [`UnpackedResponseBody`]. fn add(mut self, other: &char) -> Self { self.push_char(other); self @@ -693,7 +701,7 @@ impl Add<&str> for UnpackedResponseBody { type Output = Self; // add - /// Adds a `&str` to an [`UnpackedResponseBody`]. + /// Adds a [`&str`](str) to an [`UnpackedResponseBody`]. fn add(mut self, other: &str) -> Self { self.push_str(other); self @@ -715,7 +723,7 @@ impl Add<&String> for UnpackedResponseBody { type Output = Self; // add - /// Adds a `&String` to an [`UnpackedResponseBody`]. + /// Adds a [`&String`](String) to an [`UnpackedResponseBody`]. fn add(mut self, other: &String) -> Self { self.push_str(other); self @@ -726,7 +734,7 @@ impl Add> for UnpackedResponseBody { type Output = Self; // add - /// Adds a boxed [`str`] slice to an [`UnpackedResponseBody`]. + /// Adds a [boxed](Box) [string](str) slice to an [`UnpackedResponseBody`]. fn add(mut self, other: Box) -> Self::Output { self.push_str(&other); self @@ -737,7 +745,8 @@ impl<'a> Add> for UnpackedResponseBody { type Output = Self; // add - /// Adds a clone-on-write string to an [`UnpackedResponseBody`]. + /// Adds a [clone-on-write](Cow) [string](str) to an + /// [`UnpackedResponseBody`]. fn add(mut self, other: Cow<'a, str>) -> Self::Output { self.push_str(&other); self @@ -759,7 +768,7 @@ impl Add> for UnpackedResponseBody { type Output = Self; // add - /// Adds a `Vec[u8]` to an [`UnpackedResponseBody`]. + /// Adds a [`Vec[u8]`](Vec) to an [`UnpackedResponseBody`]. fn add(mut self, other: Vec) -> Self { self.push_bytes(&other); self @@ -770,7 +779,7 @@ impl Add<&Vec> for UnpackedResponseBody { type Output = Self; // add - /// Adds a `&Vec[u8]` to an [`UnpackedResponseBody`]. + /// Adds a [`&Vec[u8]`](Vec) to an [`UnpackedResponseBody`]. fn add(mut self, other: &Vec) -> Self { self.push_bytes(other); self @@ -781,7 +790,7 @@ impl Add for UnpackedResponseBody { type Output = Self; // add - /// Adds an `UnpackedResponseBody` to an [`UnpackedResponseBody`]. + /// Adds an [`UnpackedResponseBody`] to an [`UnpackedResponseBody`]. fn add(mut self, other: Self) -> Self { self.push_bytes(&other.body); self @@ -792,7 +801,8 @@ impl Add<&UnpackedResponseBody> for UnpackedResponseBody { type Output = Self; // add - /// Adds an `&UnpackedResponseBody` to an [`UnpackedResponseBody`]. + /// Adds an [`&UnpackedResponseBody`](UnpackedResponseBody) to an + /// [`UnpackedResponseBody`]. fn add(mut self, other: &Self) -> Self { self.push_bytes(other.as_bytes()); self @@ -801,7 +811,8 @@ impl Add<&UnpackedResponseBody> for UnpackedResponseBody { impl AddAssign<&[u8]> for UnpackedResponseBody { // add_assign - /// Adds a `&[u8]` to an [`UnpackedResponseBody`]. + /// Adds a [`&[u8]`](https://doc.rust-lang.org/std/primitive.slice.html) to + /// an [`UnpackedResponseBody`]. fn add_assign(&mut self, other: &[u8]) { self.push_bytes(other); } @@ -809,7 +820,8 @@ impl AddAssign<&[u8]> for UnpackedResponseBody { impl AddAssign<&[u8; N]> for UnpackedResponseBody { // add_assign - /// Adds a `&[u8; N]` to an [`UnpackedResponseBody`]. + /// Adds a [`&[u8; N]`](https://doc.rust-lang.org/std/primitive.slice.html) + /// to an [`UnpackedResponseBody`]. fn add_assign(&mut self, other: &[u8; N]) { self.push_bytes(other); } @@ -825,7 +837,7 @@ impl AddAssign for UnpackedResponseBody { impl AddAssign<&char> for UnpackedResponseBody { // add_assign - /// Adds a `&char` to an [`UnpackedResponseBody`]. + /// Adds a [`&char`](char) to an [`UnpackedResponseBody`]. fn add_assign(&mut self, other: &char) { self.push_char(other); } @@ -833,7 +845,7 @@ impl AddAssign<&char> for UnpackedResponseBody { impl AddAssign<&str> for UnpackedResponseBody { // add_assign - /// Adds a `&str` to an [`UnpackedResponseBody`]. + /// Adds a [`&str`](str) to an [`UnpackedResponseBody`]. fn add_assign(&mut self, other: &str) { self.push_str(other); } @@ -849,7 +861,7 @@ impl AddAssign for UnpackedResponseBody { impl AddAssign<&String> for UnpackedResponseBody { // add_assign - /// Adds a `&String` to an [`UnpackedResponseBody`]. + /// Adds a [`&String`](String) to an [`UnpackedResponseBody`]. fn add_assign(&mut self, other: &String) { self.push_str(other); } @@ -857,7 +869,7 @@ impl AddAssign<&String> for UnpackedResponseBody { impl AddAssign> for UnpackedResponseBody { // add_assign - /// Adds a boxed [`str`] slice to an [`UnpackedResponseBody`]. + /// Adds a [boxed](Box) [string](str) slice to an [`UnpackedResponseBody`]. fn add_assign(&mut self, other: Box) { self.push_str(&other); } @@ -865,7 +877,8 @@ impl AddAssign> for UnpackedResponseBody { impl<'a> AddAssign> for UnpackedResponseBody { // add_assign - /// Adds a clone-on-write string to an [`UnpackedResponseBody`]. + /// Adds a [clone-on-write](Cow) [string](str) to an + /// [`UnpackedResponseBody`]. fn add_assign(&mut self, other: Cow<'a, str>){ self.push_str(&other); } @@ -881,7 +894,7 @@ impl AddAssign for UnpackedResponseBody { impl AddAssign> for UnpackedResponseBody { // add_assign - /// Adds a `Vec` to an [`UnpackedResponseBody`]. + /// Adds a [`Vec[u8]`](Vec) to an [`UnpackedResponseBody`]. fn add_assign(&mut self, other: Vec) { self.push_bytes(&other); } @@ -889,7 +902,7 @@ impl AddAssign> for UnpackedResponseBody { impl AddAssign<&Vec> for UnpackedResponseBody { // add_assign - /// Adds a `&Vec` to an [`UnpackedResponseBody`]. + /// Adds a [`&Vec[u8]`](Vec) to an [`UnpackedResponseBody`]. fn add_assign(&mut self, other: &Vec) { self.push_bytes(other); } @@ -897,7 +910,7 @@ impl AddAssign<&Vec> for UnpackedResponseBody { impl AddAssign for UnpackedResponseBody { // add_assign - /// Adds an `UnpackedResponseBody` to an [`UnpackedResponseBody`]. + /// Adds an [`UnpackedResponseBody`] to an [`UnpackedResponseBody`]. fn add_assign(&mut self, other: Self) { self.push_bytes(&other.body); } @@ -905,7 +918,8 @@ impl AddAssign for UnpackedResponseBody { impl AddAssign<&UnpackedResponseBody> for UnpackedResponseBody { // add_assign - /// Adds an `&UnpackedResponseBody` to an [`UnpackedResponseBody`]. + /// Adds an [`&UnpackedResponseBody`](UnpackedResponseBody) to an + /// [`UnpackedResponseBody`]. fn add_assign(&mut self, other: &Self) { self.push_bytes(other.as_bytes()); } @@ -953,9 +967,9 @@ impl Display for UnpackedResponseBody { /// /// This method serialises the response body based on the content type. If /// the content type is [`ContentType::Text`], then the response body is - /// serialised to an ordinary `String`. If the content type is + /// serialised to an ordinary [`String`]. If the content type is /// [`ContentType::Binary`], then the response body is serialised to a - /// base64-encoded `String`. + /// base64-encoded [`String`]. /// /// Note that as no validation checks are performed on the response body /// contents, it is not guaranteed to be UTF8, and therefore if not @@ -964,7 +978,7 @@ impl Display for UnpackedResponseBody { /// conversion of the response body bytes to a UTF8 string will be lossy if /// there are invalid characters. /// - /// # See Also + /// # See also /// /// * [`UnpackedResponseBody::serialize()`] /// * [`UnpackedResponseBody::to_base64()`] @@ -980,7 +994,8 @@ impl Display for UnpackedResponseBody { impl From<&[u8]> for UnpackedResponseBody { // from - /// Converts a `&[u8]` to an [`UnpackedResponseBody`]. + /// Converts a [`&[u8]`](https://doc.rust-lang.org/std/primitive.slice.html) + /// to an [`UnpackedResponseBody`]. fn from(b: &[u8]) -> Self { UnpackedResponseBody { body: b.to_vec(), ..Default::default() } } @@ -988,7 +1003,8 @@ impl From<&[u8]> for UnpackedResponseBody { impl From<&[u8; N]> for UnpackedResponseBody { // from - /// Converts a `&[u8; N]` to an [`UnpackedResponseBody`]. + /// Converts a [`&[u8; N]`](https://doc.rust-lang.org/std/primitive.slice.html) + /// to an [`UnpackedResponseBody`]. fn from(b: &[u8; N]) -> Self { UnpackedResponseBody { body: b.to_vec(), ..Default::default() } } @@ -1000,27 +1016,27 @@ impl From for UnpackedResponseBody { /// /// Note that it does this in the way that is most compatible with /// [`String`] conversion. The [`char`] type in Rust represents a Unicode - /// scalar value. That means a single `char` value corresponds to one + /// scalar value. That means a single [`char`] value corresponds to one /// Unicode character. But Unicode characters can have a wide range of /// values, from `0` to `0x10FFFF` (this range excludes the surrogate /// pairs), and this value range doesn't fit into a single byte. That's why - /// `char` in Rust is 4 bytes, because it has to accommodate any possible - /// Unicode scalar value. The UTF-8 encoded representation of the 'ñ' - /// character is `[195, 177`, but in memory, a `char` containing `'ñ'` does - /// not hold the bytes `[195, 177]`. Instead, it holds the Unicode scalar - /// value for 'ñ', which is `U+00F1`, or in integer terms, `241`. When we - /// convert a char to a [`u32`] directly, we're taking this scalar value - /// (like `241` for `'ñ'`) and representing it in memory as a 4-byte - /// integer. So using code such as `(c as u32).to_le_bytes().to_vec()` would - /// result in [241, 0, 0, 0], and not [195, 177]. This behaviour would not - /// match expectation and would not match the behaviour of [`String`] - /// conversion. To get the UTF-8 encoded bytes of a `char`, we need to use - /// encoding methods because we're effectively translating from the Unicode - /// scalar value to its UTF-8 byte sequence. This is what the - /// [`encode_utf8()`](char::encode_utf8()) method provides. To put it - /// another way: `char` isn't storing bytes, it's storing a Unicode scalar - /// value. UTF-8 is one of the ways to represent that value (and the most - /// common one in Rust). + /// [`char`] in Rust is 4 bytes, because it has to accommodate any possible + /// Unicode scalar value. The UTF-8 encoded representation of the `ñ` + /// character is `[195, 177]`, but in memory, a [`char`] containing `'ñ'` + /// does not hold the bytes `[195, 177]`. Instead, it holds the Unicode + /// scalar value for `ñ`, which is `U+00F1`, or in integer terms, `241`. + /// When we convert a [`char`] to a [`u32`] directly, we're taking this + /// scalar value (like `241` for `ñ`) and representing it in memory as a + /// 4-byte integer. So using code such as + /// `(c as u32).to_le_bytes().to_vec()` would result in [241, 0, 0, 0], and + /// not [195, 177]. This behaviour would not match expectation and would not + /// match the behaviour of [`String`] conversion. To get the UTF-8 encoded + /// bytes of a [`char`], we need to use encoding methods because we're + /// effectively translating from the Unicode scalar value to its UTF-8 byte + /// sequence. This is what the [`encode_utf8()`](char::encode_utf8()) method + /// provides. To put it another way: [`char`] isn't storing bytes, it's + /// storing a Unicode scalar value. UTF-8 is one of the ways to represent + /// that value (and the most common one in Rust). /// fn from(c: char) -> Self { let mut bytes = [0; 4]; @@ -1031,7 +1047,7 @@ impl From for UnpackedResponseBody { impl From<&char> for UnpackedResponseBody { // from - /// Converts a `&char` to an [`UnpackedResponseBody`]. + /// Converts a [`&char`](char) to an [`UnpackedResponseBody`]. fn from(c: &char) -> Self { Self::from(c.to_owned()) } @@ -1047,7 +1063,8 @@ impl From for UnpackedResponseBody { impl From<&Json> for UnpackedResponseBody { // from - /// Converts a `&serde_json::Value` to an [`UnpackedResponseBody`]. + /// Converts a [`&serde_json::Value`](serde_json::Value) to an + /// [`UnpackedResponseBody`]. fn from(j: &Json) -> Self { Self { body: j.to_string().into_bytes(), ..Default::default() } } @@ -1055,7 +1072,7 @@ impl From<&Json> for UnpackedResponseBody { impl From<&str> for UnpackedResponseBody { // from - /// Converts a `&str` to an [`UnpackedResponseBody`]. + /// Converts a [`&str`](str) to an [`UnpackedResponseBody`]. fn from(s: &str) -> Self { Self { body: s.to_owned().as_bytes().to_vec(), ..Default::default() } } @@ -1063,7 +1080,7 @@ impl From<&str> for UnpackedResponseBody { impl From<&mut str> for UnpackedResponseBody { // from - /// Converts a `&mut str` to an [`UnpackedResponseBody`]. + /// Converts a [`&mut str`](str) to an [`UnpackedResponseBody`]. fn from(s: &mut str) -> Self { Self { body: s.to_owned().as_bytes().to_vec(), ..Default::default() } } @@ -1079,7 +1096,7 @@ impl From for UnpackedResponseBody { impl From<&String> for UnpackedResponseBody { // from - /// Converts a `&String` to an [`UnpackedResponseBody`]. + /// Converts a [`&String`](String) to an [`UnpackedResponseBody`]. fn from(s: &String) -> Self { Self { body: s.as_str().as_bytes().to_vec(), ..Default::default() } } @@ -1087,7 +1104,8 @@ impl From<&String> for UnpackedResponseBody { impl From> for UnpackedResponseBody { // from - /// Converts a boxed [`str`] slice to an [`UnpackedResponseBody`]. + /// Converts a [boxed](Box) [string](str) slice to an + /// [`UnpackedResponseBody`]. fn from(s: Box) -> Self { Self { body: s.into_string().into_bytes(), ..Default::default() } } @@ -1095,7 +1113,8 @@ impl From> for UnpackedResponseBody { impl<'a> From> for UnpackedResponseBody { // from - /// Converts a clone-on-write string to an [`UnpackedResponseBody`]. + /// Converts a [clone-on-write](Cow) [string](str) to an + /// [`UnpackedResponseBody`]. fn from(s: Cow<'a, str>) -> Self { Self { body: s.into_owned().into_bytes(), ..Default::default() } } @@ -1111,7 +1130,7 @@ impl From for UnpackedResponseBody { impl From> for UnpackedResponseBody { // from - /// Converts a `Vec` to an [`UnpackedResponseBody`]. + /// Converts a [`Vec[u8]`](Vec) to an [`UnpackedResponseBody`]. fn from(v: Vec) -> Self { Self { body: v, ..Default::default() } } @@ -1119,7 +1138,7 @@ impl From> for UnpackedResponseBody { impl From<&Vec> for UnpackedResponseBody { // from - /// Converts a `&Vec` to an [`UnpackedResponseBody`]. + /// Converts a [`&Vec[u8]`](Vec) to an [`UnpackedResponseBody`]. fn from(v: &Vec) -> Self { Self { body: v.clone(), ..Default::default() } } @@ -1147,9 +1166,9 @@ impl Serialize for UnpackedResponseBody { /// /// This method serialises the response body based on the content type. If /// the content type is [`ContentType::Text`], then the response body is - /// serialised to an ordinary `String`. If the content type is + /// serialised to an ordinary [`String`]. If the content type is /// [`ContentType::Binary`], then the response body is serialised to a - /// base64-encoded `String`. + /// base64-encoded [`String`]. /// /// Note that as no validation checks are performed on the response body /// contents, it is not guaranteed to be UTF8, and therefore if not @@ -1158,7 +1177,7 @@ impl Serialize for UnpackedResponseBody { /// conversion of the response body bytes to a UTF8 string will be lossy if /// there are invalid characters. /// - /// # See Also + /// # See also /// /// * [`UnpackedResponseBody::deserialize()`] /// * [`UnpackedResponseBody::fmt()`] @@ -1184,14 +1203,14 @@ impl <'de> Deserialize<'de> for UnpackedResponseBody { /// fails then it will assume the content type is [`ContentType::Text`], and /// deserialises the string in standard fashion. /// - /// Note that as the incoming data is from a `String`, and Rust strings are - /// are all valid UTF8, the resulting deserialised response body is + /// Note that as the incoming data is from a [`String`], and Rust strings + /// are are all valid UTF8, the resulting deserialised response body is /// guaranteed to be UTF8 if the content type is determined to be - /// `ContentType::Text`. If base64 is detected then the deserialised bytes + /// [`ContentType::Text`]. If base64 is detected then the deserialised bytes /// are not guaranteed to be valid UTF8, as no validation checks of that /// nature are performed against the response body. /// - /// # See Also + /// # See also /// /// * [`UnpackedResponseBody::deserialize()`] /// * [`UnpackedResponseBody::from_base64()`] @@ -1242,7 +1261,7 @@ pub trait ResponseExt { /// body matches, this is fine, as the data is known and constrained, and /// memory/performance is less of a concern. /// - /// # See Also + /// # See also /// /// * [`axum::response`] /// * [`axum::response::Response`] @@ -1305,7 +1324,7 @@ impl ResponseExt for Response { /// value, allowing for reliable comparison. Sorting does break the original /// order of the headers, but this should only very rarely matter. /// -/// # See Also +/// # See also /// /// * [`ResponseExt::unpack()`] /// * [`UnpackedResponse`] @@ -1331,8 +1350,9 @@ fn convert_headers(headermap: &HeaderMap) -> Vec) -> Vec