///
/// # Examples
///
- /// Using `AsMut` as trait bound for a generic function we can accept all mutable references
- /// that can be converted to type `&mut T`. Because [`Box<T>`] implements `AsMut<T>` we can
- /// write a function `add_one` that takes all arguments that can be converted to `&mut u64`.
- /// Because [`Box<T>`] implements `AsMut<T>`, `add_one` accepts arguments of type
- /// `&mut Box<u64>` as well:
+ /// Using `AsMut` as trait bound for a generic function, we can accept all mutable references that
+ /// can be converted to type `&mut T`. Unlike [dereference], which has a single [target type],
+ /// there can be multiple implementations of `AsMut` for a type. In particular, `Vec<T>` implements
+ /// both `AsMut<Vec<T>>` and `AsMut<[T]>`.
+ ///
+ /// In the following, the example functions `caesar` and `null_terminate` provide a generic
+ /// interface which work with any type that can be converted by cheap mutable-to-mutable conversion
+ /// into a byte slice (`[u8]`) or byte vector (`Vec<u8>`), respectively.
+ ///
+ /// [dereference]: core::ops::DerefMut
+ /// [target type]: core::ops::Deref::Target
///
/// ```
- /// fn add_one<T: AsMut<u64>>(num: &mut T) {
- /// *num.as_mut() += 1;
+ /// struct Document {
+ /// info: String,
+ /// content: Vec<u8>,
+ /// }
+ ///
+ /// impl<T: ?Sized> AsMut<T> for Document
+ /// where
+ /// Vec<u8>: AsMut<T>,
+ /// {
+ /// fn as_mut(&mut self) -> &mut T {
+ /// self.content.as_mut()
+ /// }
/// }
///
- /// let mut boxed_num = Box::new(0);
- /// add_one(&mut boxed_num);
- /// assert_eq!(*boxed_num, 1);
+ /// fn caesar<T: AsMut<[u8]>>(data: &mut T, key: u8) {
+ /// for byte in data.as_mut() {
+ /// *byte = byte.wrapping_add(key);
+ /// }
+ /// }
+ ///
+ /// fn null_terminate<T: AsMut<Vec<u8>>>(data: &mut T) {
+ /// // Using a non-generic inner function, which contains most of the
+ /// // functionality, helps to minimize monomorphization overhead.
+ /// fn doit(data: &mut Vec<u8>) {
+ /// let len = data.len();
+ /// if len == 0 || data[len-1] != 0 {
+ /// data.push(0);
+ /// }
+ /// }
+ /// doit(data.as_mut());
+ /// }
+ ///
+ /// fn main() {
+ /// let mut v: Vec<u8> = vec![1, 2, 3];
+ /// caesar(&mut v, 5);
+ /// assert_eq!(v, [6, 7, 8]);
+ /// null_terminate(&mut v);
+ /// assert_eq!(v, [6, 7, 8, 0]);
+ /// let mut doc = Document {
+ /// info: String::from("Example"),
+ /// content: vec![17, 19, 8],
+ /// };
+ /// caesar(&mut doc, 1);
+ /// assert_eq!(doc.content, [18, 20, 9]);
+ /// null_terminate(&mut doc);
+ /// assert_eq!(doc.content, [18, 20, 9, 0]);
+ /// }
/// ```
///
- /// [`Box<T>`]: ../../std/boxed/struct.Box.html
+ /// Note, however, that APIs don't need to be generic. In many cases taking a `&mut [u8]` or
+ /// `&mut Vec<u8>`, for example, is the better choice (callers need to pass the correct type then).
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "AsMut")]
+#[const_trait]
pub trait AsMut<T: ?Sized> {
/// Converts this type into a mutable reference of the (usually inferred) input type.
#[stable(feature = "rust1", since = "1.0.0")]