write_ref/
lib.rs

1#![deny(missing_docs)]
2
3//! Write-only references.
4//!
5//! Many functions in Rust's standard library, such as `char::encode_utf8`, take
6//! a mutable reference that they only ever write to.
7//!
8//! This crate provides a way to express this guarantee:
9//!
10//! - `WriteRef<T>` provides a single method, `write`. By taking this as a
11//!   parameter, a function guarantees that it will only ever write to it.
12//! - `WriteSlice<T>` works similarly, but it allows writing only to individual
13//!   elements. This is useful for functions that write to a provided buffer,
14//!   such as `char::encode_utf8`.
15//!
16//! Most functions should not take a `WriteRef` or `WriteSlice` directly;
17//! instead, they should take an `impl Into<WriteRef<'a, T>>` so that callers
18//! can pass in a `&mut T`.
19
20use std::convert::From;
21
22/// Represents a write-only reference.
23///
24/// It is generally advised to take an `impl Into<WriteRef>` instead of a
25/// `WriteRef` itself in APIs so that callers can pass in a mutable reference.
26///
27/// # Examples
28///
29/// ```
30/// # extern crate write_ref;
31/// # use write_ref::WriteRef;
32/// # fn main() {
33/// let mut a = 3;
34/// {
35///     let mut a_ref = WriteRef::from(&mut a);
36///     a_ref.write(0);
37/// }
38/// assert_eq!(a, 0);
39/// # }
40/// ```
41pub struct WriteRef<'a, T: 'a>(&'a mut T);
42
43impl<'a, T: 'a> WriteRef<'a, T> {
44    /// Write a value to this reference.
45    pub fn write(&mut self, val: T) {
46        *self.0 = val;
47    }
48}
49
50impl<'a, T: 'a> From<&'a mut T> for WriteRef<'a, T> {
51    fn from(inner: &'a mut T) -> Self {
52        WriteRef(inner)
53    }
54}
55
56/// Represents a write-only buffer.
57///
58/// You only write to individual elements of this slice; you can't modify the
59/// slice itself or read from its elements.
60///
61/// It is generally advised to take an `impl Into<WriteSlice>` instead of a
62/// `WriteSlice` itself in APIs so that callers can pass in a a mutable
63/// reference.
64///
65/// # Examples
66///
67/// ```
68/// # extern crate write_ref;
69/// # use write_ref::WriteSlice;
70/// fn copy<'a, T: Clone + 'a>(input: &[T], output: impl Into<WriteSlice<'a, T>>) {
71///     let mut output = output.into();
72///     for (i, val) in input.iter().enumerate() {
73///         output.write(i, val.clone());
74///     }
75/// }
76/// fn main() {
77///     let input = [1, 2, 3];
78///     let mut output = [7, 1, 9];
79///     copy(&input, &mut output as &mut [_]);
80///     assert_eq!(input, output);
81/// }
82/// ```
83pub struct WriteSlice<'a, T: 'a>(&'a mut [T]);
84
85impl<'a, T: 'a> WriteSlice<'a, T> {
86    /// Write a value to an element of this slice.
87    ///
88    /// # Panics
89    ///
90    /// Panics if `idx` is out of bounds.
91    pub fn write(&mut self, idx: usize, val: T) {
92        self.0[idx] = val;
93    }
94}
95
96impl<'a, T: 'a> From<&'a mut [T]> for WriteSlice<'a, T> {
97    fn from(inner: &'a mut [T]) -> Self {
98        WriteSlice(inner)
99    }
100}