docs(to): fix docstrings and add examples

Signed-off-by: Paul Spooren <mail@aparcar.org>
This commit is contained in:
Paul Spooren
2024-11-08 12:44:30 +01:00
parent 1d1c0e9da7
commit 05fbaff2dc
6 changed files with 87 additions and 6 deletions

View File

@@ -1,3 +1,5 @@
#![warn(missing_docs)]
#![recursion_limit = "256"]
#![doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/README.md"))]
#[cfg(doctest)]

View File

@@ -5,23 +5,70 @@ use crate::CondenseBeside;
pub struct Beside<Val, Ret>(pub Val, pub Ret);
impl<Val, Ret> Beside<Val, Ret> {
/// Get an immutable reference to the destination value
///
/// # Example
/// ```
/// use rosenpass_to::Beside;
///
/// let beside = Beside(1, 2);
/// assert_eq!(beside.dest(), &1);
/// ```
pub fn dest(&self) -> &Val {
&self.0
}
/// Get an immutable reference to the return value
///
/// # Example
/// ```
/// use rosenpass_to::Beside;
///
/// let beside = Beside(1, 2);
/// assert_eq!(beside.ret(), &2);
/// ```
pub fn ret(&self) -> &Ret {
&self.1
}
/// Get a mutable reference to the destination value
///
/// # Example
/// ```
/// use rosenpass_to::Beside;
///
/// let mut beside = Beside(1, 2);
/// *beside.dest_mut() = 3;
/// assert_eq!(beside.dest(), &3);
/// ```
pub fn dest_mut(&mut self) -> &mut Val {
&mut self.0
}
/// Get a mutable reference to the return value
///
/// # Example
/// ```
/// use rosenpass_to::Beside;
///
/// let mut beside = Beside(1, 2);
/// *beside.ret_mut() = 3;
/// assert_eq!(beside.ret(), &3);
/// ```
pub fn ret_mut(&mut self) -> &mut Ret {
&mut self.1
}
/// Perform beside condensation. See [CondenseBeside]
///
/// # Example
/// ```
/// use rosenpass_to::Beside;
/// use rosenpass_to::CondenseBeside;
///
/// let beside = Beside(1, ());
/// assert_eq!(beside.condense(), 1);
/// ```
pub fn condense(self) -> <Ret as CondenseBeside<Val>>::Condensed
where
Ret: CondenseBeside<Val>,

View File

@@ -7,8 +7,10 @@
/// The function [Beside::condense()](crate::Beside::condense) is a shorthand for using the
/// condense trait.
pub trait CondenseBeside<Val> {
/// The type that results from condensation.
type Condensed;
/// Takes ownership of `self` and condenses it with the given value.
fn condense(self, ret: Val) -> Self::Condensed;
}

View File

@@ -1,6 +1,7 @@
/// Helper performing explicit unsized coercion.
/// Used by the [to](crate::to()) function.
pub trait DstCoercion<Dst: ?Sized> {
/// Performs an explicit coercion to the destination type.
fn coerce_dest(&mut self) -> &mut Dst;
}

View File

@@ -1,13 +1,16 @@
use crate::{Beside, CondenseBeside};
use std::borrow::BorrowMut;
// The To trait is the core of the to crate; most functions with destinations will either return
// an object that is an instance of this trait or they will return `-> impl To<Destination,
// Return_value`.
//
// A quick way to implement a function with destination is to use the
// [with_destination(|param: &mut Type| ...)] higher order function.
/// The To trait is the core of the to crate; most functions with destinations will either return
/// an object that is an instance of this trait or they will return `-> impl To<Destination,
/// Return_value`.
///
/// A quick way to implement a function with destination is to use the
/// [with_destination(|param: &mut Type| ...)] higher order function.
pub trait To<Dst: ?Sized, Ret>: Sized {
/// Writes self to the destination `out` and returns a value of type `Ret`.
///
/// This is the core method that must be implemented by all types implementing `To`.
fn to(self, out: &mut Dst) -> Ret;
/// Generate a destination on the fly with a lambda.

View File

@@ -1,20 +1,38 @@
use crate::To;
use std::marker::PhantomData;
/// A struct that wraps a closure and implements the `To` trait
///
/// This allows passing closures that operate on a destination type `Dst`
/// and return `Ret`.
///
/// # Type Parameters
/// * `Dst` - The destination type the closure operates on
/// * `Ret` - The return type of the closure
/// * `Fun` - The closure type that implements `FnOnce(&mut Dst) -> Ret`
struct ToClosure<Dst, Ret, Fun>
where
Dst: ?Sized,
Fun: FnOnce(&mut Dst) -> Ret,
{
/// The function to call.
fun: Fun,
/// Phantom data to hold the destination type
_val: PhantomData<Box<Dst>>,
}
/// Implementation of the `To` trait for ToClosure
///
/// This enables calling the wrapped closure with a destination reference.
impl<Dst, Ret, Fun> To<Dst, Ret> for ToClosure<Dst, Ret, Fun>
where
Dst: ?Sized,
Fun: FnOnce(&mut Dst) -> Ret,
{
/// Execute the wrapped closure with the given destination
///
/// # Arguments
/// * `out` - Mutable reference to the destination
fn to(self, out: &mut Dst) -> Ret {
(self.fun)(out)
}
@@ -22,6 +40,14 @@ where
/// Used to create a function with destination.
///
/// Creates a wrapper that implements the `To` trait for a closure that
/// operates on a destination type.
///
/// # Type Parameters
/// * `Dst` - The destination type the closure operates on
/// * `Ret` - The return type of the closure
/// * `Fun` - The closure type that implements `FnOnce(&mut Dst) -> Ret`
///
/// See the tutorial in [readme.me]..
pub fn with_destination<Dst, Ret, Fun>(fun: Fun) -> impl To<Dst, Ret>
where