diff --git a/.lefthook.yml b/.lefthook.yml index 3b14376..749684f 100644 --- a/.lefthook.yml +++ b/.lefthook.yml @@ -1,4 +1,4 @@ pre-commit: commands: quality: - run: make + run: make deny-commit-on-master && make diff --git a/Makefile b/Makefile index c0398a8..af734c8 100644 --- a/Makefile +++ b/Makefile @@ -50,3 +50,8 @@ dev: echo Installing cargo-fuzz... cargo install cargo-fuzz + +deny-commit-on-master: +ifeq ($(shell git symbolic-ref --short HEAD),master) + $(error Direct commits to 'master' are not allowed.) +endif diff --git a/README.md b/README.md index f382836..0c61c9a 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ All operations are O(1) except: | `clear` | O(current length) | O(1) | | `set_len` | O(new length - current length) | O(new length - current length) | | `extend_from_slice` | O(slice length) | O(slice length) | +| `append` | O(other vector length) | O(other vector length) | ## Add to project diff --git a/src/lib.rs b/src/lib.rs index db85540..3e56b71 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -637,6 +637,45 @@ impl Vec { Ok(()) } + /// Moves elements of `other` vector at the end of the current vector. `other` will be empty. + /// + /// # Errors + /// + /// Returns [`CapacityError`] if adding elements from `other` would result in current vector exceeding its capacity. + /// + /// # Example + /// + /// ```rust + /// use static_vector::Vec; + /// + /// let mut vec = Vec::::new(); + /// vec.push(1).unwrap(); + /// vec.push(2).unwrap(); + /// vec.push(3).unwrap(); + /// + /// let mut other = Vec::::new(); + /// other.push(4).unwrap(); + /// other.push(5).unwrap(); + /// other.push(6).unwrap(); + /// + /// vec.append(&mut other).unwrap(); + /// assert_eq!(vec.as_slice(), [1, 2, 3, 4, 5, 6]); + /// assert_eq!(other.as_slice(), []); + /// ``` + #[inline] + pub fn append( + &mut self, + other: &mut Vec, + ) -> Result<(), CapacityError> + where + T: Clone, + { + self.extend_from_slice(other.as_slice())?; + other.clear(); + + Ok(()) + } + /// Adds the given `value` to the end of the vector without checking bounds. /// For internal and controlled use only. fn push_unchecked(&mut self, value: T) { @@ -1397,6 +1436,44 @@ mod tests { assert_eq!(dst.as_slice(), [1, 2, 3]); } + #[test] + fn append_with_enough_room() { + let mut vec = Vec::::new(); + vec.push(1).unwrap(); + vec.push(2).unwrap(); + + let mut other = Vec::::new(); + other.push(3).unwrap(); + other.push(4).unwrap(); + + let result = vec.append(&mut other); + + assert!(result.is_ok()); + assert_eq!(vec.len(), 4); + assert_eq!(vec.as_slice(), [1, 2, 3, 4]); + assert!(other.is_empty()); + assert_eq!(other.as_slice(), []); + } + + #[test] + fn append_with_not_enough_room() { + let mut vec = Vec::::new(); + vec.push(1).unwrap(); + vec.push(2).unwrap(); + + let mut other = Vec::::new(); + other.push(3).unwrap(); + other.push(4).unwrap(); + + let result = vec.append(&mut other); + + assert!(result.is_err()); + assert_eq!(vec.len(), 2); + assert_eq!(vec.as_slice(), [1, 2]); + assert_eq!(other.len(), 2); + assert_eq!(other.as_slice(), [3, 4]); + } + #[test] fn clone() { let mut vec = Vec::::new();