Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow concatenation of different array strings #269

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions src/array_string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,68 @@ impl<const CAP: usize> ArrayString<CAP>
}
}

/// Adds the given `ArrayString` to the end of this `ArrayString`.
///
/// ***Panics*** if the backing array is not large enough to fit the additional `ArrayString`.
///
/// ```
/// use std::str::FromStr;
/// use arrayvec::ArrayString;
///
/// let mut string = ArrayString::<2>::new();
/// let a = ArrayString::<1>::from_str("a").unwrap();
/// let b = ArrayString::<1>::from_str("b").unwrap();
///
/// string.push_array_string(a);
/// string.push_array_string(b);
///
/// assert_eq!(&string[..], "ab");
/// ```
#[track_caller]
pub fn push_array_string<const OTHER_CAP: usize>(&mut self, other: ArrayString<OTHER_CAP>) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The user should just use string.push_str(&a) here. Is there a reason not to do that?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah would this work? I actually didn't know that! I assume this would also avoid heap allocs?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

of course, no heap allocations extra. ArrayString is just like another kind of String - they both have zero cost deref to &str.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah perfect this can likely get closed out then!

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, feel free to add an example that shows how this works, if you want to.

self.try_push_array_string(other).unwrap();
}

/// Adds the given `ArrayString` to the end of this `ArrayString`.
///
/// Returns `Ok` if the push succeeds.
///
/// **Errors** if the backing array is not large enough to fit the additional characters.
///
/// ```
/// use std::str::FromStr;
/// use arrayvec::ArrayString;
///
/// let mut string = ArrayString::<6>::new();
/// let foo = ArrayString::<3>::from_str("foo").unwrap();
/// let bar = ArrayString::<3>::from_str("bar").unwrap();
/// let baz = ArrayString::<3>::from_str("baz").unwrap();
///
/// string.try_push_array_string(foo).unwrap();
/// string.try_push_array_string(bar).unwrap();
/// let overflow = string.try_push_array_string(baz);
///
/// assert_eq!(&string[..], "foobar");
/// assert_eq!(overflow.unwrap_err().element(), ArrayString::from_str("baz").unwrap());
/// ```
pub fn try_push_array_string<const OTHER_CAP: usize>(
&mut self,
other: ArrayString<OTHER_CAP>,
) -> Result<(), CapacityError<ArrayString<OTHER_CAP>>> {
if other.len() > self.capacity() - self.len() {
return Err(CapacityError::new(other));
}
unsafe {
let dst = self.as_mut_ptr().add(self.len());
Callum-A marked this conversation as resolved.
Show resolved Hide resolved
let src = other.as_ptr();
ptr::copy_nonoverlapping(src, dst, other.len());
let newl = self.len() + other.len();
self.set_len(newl);
}

Ok(())
}

/// Adds the given string slice to the end of the string.
///
/// ***Panics*** if the backing array is not large enough to fit the string.
Expand Down