1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
//! Extension methods for copying strings into a string.
//!
//! This crate provides [`copy_from_str`] function which can be used to
//! mutate Rust strings. It works similarly to [`copy_from_slice`] from
//! standard library except it is for strings.
//!
//! # Examples
//!
//! ```
//! use copy_from_str::CopyFromStrExt;
//!
//! fn make_ascii_uppercase(mut input: &mut str) {
//!     let mut buffer = [0; 4];
//!     while let Some(ch) = input.chars().next() {
//!         let src = ch.to_ascii_uppercase().encode_utf8(&mut buffer);
//!         let (to_uppercase, rest) = { input }.split_at_mut(ch.len_utf8());
//!         to_uppercase.copy_from_str(src);
//!         input = rest;
//!     }
//! }
//!
//! let mut str = String::from("Hello, world! 💯");
//! make_ascii_uppercase(&mut str);
//! assert_eq!(str, "HELLO, WORLD! 💯");
//! ```
//!
//! [`copy_from_str`]: trait.CopyFromStrExt.html#tymethod.copy_from_str
//! [`copy_from_slice`]: https://doc.rust-lang.org/std/primitive.slice.html#method.copy_from_slice

#![deny(missing_docs)]
#![recursion_limit = "256"]
#![no_std]
#[macro_use]
extern crate extension_trait;

extension_trait! {
    /// Extension method for copying a string into another string.
    pub CopyFromStrExt for str {
        /// Copies all elements from `src` into `self`, using a memcpy.
        ///
        /// The length of `src` must be the same as `self`.
        ///
        /// # Panics
        ///
        /// This function will panic if the two strings have different lengths.
        ///
        /// # Examples
        ///
        /// Copying two elements from a string into another:
        ///
        /// ```
        /// use copy_from_str::CopyFromStrExt;
        ///
        /// let src = "abcd";
        /// let mut dst = String::from("  ");
        ///
        /// dst.copy_from_str(&src[2..]);
        ///
        /// assert_eq!(src, "abcd");
        /// assert_eq!(dst, "cd");
        /// ```
        ///
        /// Rust enforces that there can only be one mutable reference with no
        /// immutable references to a particular piece of data in a particular
        /// scope. Because of this, attempting to use `copy_from_str` on a
        /// single string will result in a compile failure:
        ///
        /// ```compile_fail
        /// use copy_from_str::CopyFromStrExt;
        ///
        /// let mut string = String::from("abcde");
        ///
        /// string[..2].copy_from_str(&string[3..]); // compile fail!
        /// ```
        ///
        /// To work around this, we can use [`split_at_mut`] to create two distinct
        /// sub-strings from a string:
        ///
        /// ```
        /// use copy_from_str::CopyFromStrExt;
        ///
        /// let mut string = String::from("abcde");
        ///
        /// {
        ///     let (left, right) = string.split_at_mut(2);
        ///     left.copy_from_str(&right[1..]);
        /// }
        ///
        /// assert_eq!(string, "decde");
        /// ```
        ///
        /// [`split_at_mut`]: https://doc.rust-lang.org/std/primitive.str.html#method.split_at_mut
        #[inline]
        fn copy_from_str(&mut self, src: &str) {
            unsafe { self.as_bytes_mut() }.copy_from_slice(src.as_bytes());
        }
    }
}