Repository: ParkMyCar/compact_str
Pull request #229 (2022-10-23 18:28:40)

perf: Refactor underlying buffers for branchless access
This PR refactors the underlying `InlineString` and `BoxString` structs in a major way to allow for branch-less string accesses. It also renames these structs to `InlineBuffer` and `HeapBuffer`, treating these types strictly as "buffers". We also move string operations into `Repr` (e.g. pushing and popping), which de-dupes code.

ParkMyCar: Thanks for the review @NobodyXu! I'll update the PR soon with the feedback :) 

Patch:
diff --git a/.github/workflows/cross_platform.yml b/.github/workflows/cross_platform.yml
index 7b479e21..09110f44 100644
--- a/.github/workflows/cross_platform.yml
+++ b/.github/workflows/cross_platform.yml
@@ -86,25 +86,6 @@ jobs:
           command: miri
           args: test --all-features --manifest-path=compact_str/Cargo.toml
 
-  # TODO(parkmycar) re-enable ARMv7 builds
-  # linux_arm7:
-  #   name: Linux ARMv7
-  #   runs-on: [self-hosted, linux, ARM]
-  #   steps:
-  #     - uses: actions/checkout@v2
-  #       name: Checkout Repo
-  #     - uses: actions-rs/toolchain@v1
-  #       name: Install Rust
-  #       with:
-  #         profile: minimal
-  #         toolchain: nightly
-  #         override: true
-  #     - uses: actions-rs/cargo@v1
-  #       name: cargo test
-  #       with:
-  #         command: test
-  #         args: --release --all-features --manifest-path=compact_str/Cargo.toml
-
   linux_32bit:
     name: Linux 32-bit
     runs-on: ubuntu-latest
diff --git a/.github/workflows/fuzz.yml b/.github/workflows/fuzz.yml
index 31a27586..fa126bb3 100644
--- a/.github/workflows/fuzz.yml
+++ b/.github/workflows/fuzz.yml
@@ -70,43 +70,6 @@ jobs:
         with:
           update_existing: true
 
-  # TODO(parkmycar): Fails in CI with "error: failed to run LLVM passes: unknown pass name 'sancov'"
-  # honggfuzz_x86_64:
-  #   name: honggfuzz [x86_64]
-  #   runs-on: ubuntu-latest
-  #   env:
-  #     HFUZZ_BUILD_ARGS: "--features=honggfuzz"
-  #     HFUZZ_RUN_ARGS: "--run_time 120 --exit_upon_crash"
-  #     RUSTFLAGS: "-Znew-llvm-pass-manager=no"
-  #   steps:
-  #     - uses: actions/checkout@v2
-  #       name: Checkout compact_str
-  #     - uses: actions-rs/toolchain@v1
-  #       name: Install Rust
-  #       with:
-  #         toolchain: nightly
-  #         override: true
-  #     - name: Install Deps
-  #       run: sudo apt-get install --no-install-recommends binutils-dev libunwind8-dev
-  #     - uses: actions-rs/cargo@v1
-  #       name: Install honggfuzz
-  #       with:
-  #         command: install
-  #         toolchain: nightly
-  #         args: honggfuzz
-  #     - uses: actions-rs/cargo@v1
-  #       name: Fuzz!
-  #       with:
-  #         command: hfuzz
-  #         args: run honggfuzz
-  #     - name: File Issue (if failure found)
-  #       if: failure()
-  #       uses: JasonEtco/create-an-issue@v2.6
-  #       env:
-  #         GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-  #       with:
-  #         update_existing: true
-
   afl_x86_64:
     name: AFL++ [x86_64]
     runs-on: ubuntu-latest
@@ -177,58 +140,3 @@ jobs:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
         with:
           update_existing: true
-
-  # TODO(parkmycar): ARMv7 runner is no longer online
-  # afl_armv7:
-  #   name: AFL++ [ARMv7]
-  #   runs-on: [self-hosted, linux, ARM]
-  #   steps:
-  #     - uses: actions/checkout@v2
-  #       name: Checkout compact_str
-  #     - uses: actions-rs/toolchain@v1
-  #       name: Install Rust
-  #       with:
-  #         profile: minimal
-  #         toolchain: nightly-2022-07-01
-  #         override: true
-  #     - name: Install cargo-afl
-  #       run: |
-  #         cargo +nightly install afl --force
-  #     - name: AFL++ Build
-  #       run: |
-  #         cd fuzz
-  #         cargo +nightly afl build --bin afl --release --features=afl
-  #     - name: Set Fuzz Time
-  #       run: |
-  #         if [[ "${{github.event_name}}" == "push" || "${{github.event_name}}" == "pull_request" ]]; then
-  #           echo "fuzz_time=120" >> $GITHUB_ENV
-  #         else
-  #           echo "fuzz_time=1800" >> $GITHUB_ENV
-  #         fi
-  #         echo "${{ env.fuzz_time }}"
-  #     - name: Fuzz!
-  #       run: |
-  #         cd fuzz
-  #         mkdir afl/out
-  #         cargo +nightly afl fuzz -i afl/in -o afl/out -D -V ${{ env.fuzz_time }} ../target/release/afl
-  #     - name: Check for Crashes
-  #       run: |
-  #         if [ "$(ls -1q ./fuzz/afl/out/default/crashes/ | wc -l)" -ne 0 ]; then exit 1; fi
-  #     # AFL generates filenames with ":", which upload-artifact fails on, so we need to "detox" them
-  #     - name: Sanitize Crash Filenames (if present)
-  #       if: failure()
-  #       run: |
-  #         detox -r -v ./fuzz/afl/out/default/crashes/
-  #     - name: Upload Crashes (if present)
-  #       if: failure()
-  #       uses: actions/upload-artifact@v2
-  #       with:
-  #         name: Upload Crashes
-  #         path: ./fuzz/afl/out/default/crashes/
-  #     - name: File Issue (if failure found)
-  #       if: failure()
-  #       uses: JasonEtco/create-an-issue@v2.6
-  #       env:
-  #         GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-  #       with:
-  #         update_existing: true
diff --git a/bench/Cargo.toml b/bench/Cargo.toml
index 98989e3e..19ba0b6a 100644
--- a/bench/Cargo.toml
+++ b/bench/Cargo.toml
@@ -7,6 +7,7 @@ edition = "2021"
 
 [dependencies]
 compact_str = { path = "../compact_str" }
+compact_str_6 = { package = "compact_str", version = "0.6" }
 criterion = { version = "0.3", features = ["html_reports"] }
 iai = "0.1.1"
 smartstring = "1.0.1"
diff --git a/bench/benches/compact_str.rs b/bench/benches/compact_str.rs
index 0f1bcfa2..8b1376f9 100644
--- a/bench/benches/compact_str.rs
+++ b/bench/benches/compact_str.rs
@@ -2,6 +2,7 @@ use compact_str::{
     CompactString,
     ToCompactString,
 };
+use compact_str_6::CompactString as CompactString6;
 use criterion::{
     criterion_group,
     criterion_main,
@@ -31,7 +32,7 @@ fn bench_new(c: &mut Criterion) {
     c.bench_with_input(
         BenchmarkId::new("CompactString::new", "59 chars"),
         &"I am a very long string that will get allocated on the heap",
-        |b, word| b.iter(|| CompactString::new(word)),
+        |b, &word| b.iter(|| CompactString::from(word)),
     );
 
     c.bench_with_input(
@@ -91,5 +92,67 @@ fn bench_to_compact_string(c: &mut Criterion) {
     );
 }
 
+fn bench_repr_creation(c: &mut Criterion) {
+    let mut group = c.benchmark_group("Creation");
+
+    let words: Vec<String> = vec![0, 11, 12, 22, 23, 24, 25, 50]
+        .into_iter()
+        .map(|len| (0..len).into_iter().map(|_| 'a').collect())
+        .collect();
+
+    for word in words {
+        group.bench_with_input(
+            BenchmarkId::new("CompactString6", word.len()),
+            &word,
+            |b, w| b.iter(|| CompactString6::new(w)),
+        );
+
+        group.bench_with_input(
+            BenchmarkId::new("CompactString", word.len()),
+            &word,
+            |b, w| b.iter(|| CompactString::new(w)),
+        );
+
+        group.bench_with_input(
+            BenchmarkId::new("std::String", word.len()),
+            &word,
+            |b, w| b.iter(|| String::from(w)),
+        );
+    }
+}
+
+fn bench_repr_access(c: &mut Criterion) {
+    let mut group = c.benchmark_group("Access");
+
+    let words: Vec<String> = vec![0, 11, 12, 23, 24, 50]
+        .into_iter()
+        .map(|len| (0..len).into_iter().map(|_| 'a').collect())
+        .collect();
+
+    for word in words {
+        let compact = CompactString6::new(&word);
+        group.bench_with_input(
+            BenchmarkId::new("CompactString6", compact.len()),
+            &compact,
+            |b, c| b.iter(|| c.as_str()),
+        );
+
+        let compact = CompactString::new(&word);
+        group.bench_with_input(
+            BenchmarkId::new("CompactString", compact.len()),
+            &compact,
+            |b, c| b.iter(|| c.as_str()),
+        );
+
+        let std_str = String::from(&word);
+        group.bench_with_input(
+            BenchmarkId::new("String", std_str.len()),
+            &std_str,
+            |b, s| b.iter(|| s.as_str()),
+        );
+    }
+}
+criterion_group!(repr_benches, bench_repr_creation, bench_repr_access);
+
 criterion_group!(compact_str, bench_new, bench_to_compact_string);
-criterion_main!(compact_str);
+criterion_main!(compact_str, repr_benches);
diff --git a/compact_str/Cargo.toml b/compact_str/Cargo.toml
index 96c34f65..f14290a1 100644
--- a/compact_str/Cargo.toml
+++ b/compact_str/Cargo.toml
@@ -21,16 +21,20 @@ rkyv = { version = "0.7", optional = true }
 serde = { version = "1", optional = true }
 
 castaway = "0.2.1"
+cfg-if = "1"
 itoa = "1"
 ryu = "1"
+static_assertions = "1"
 
 [dev-dependencies]
 cfg-if = "1"
 proptest = { version = "1", default-features = false, features = ["std"] }
+quickcheck = "1"
 quickcheck_macros = "1"
 rayon = "1"
 serde = { version = "1", features = ["derive"] }
 serde_json = "1"
+test-case = "2"
 test-strategy = "0.2"
 
 [package.metadata.docs.rs]
diff --git a/compact_str/src/asserts.rs b/compact_str/src/asserts.rs
deleted file mode 100644
index 3378dbf2..00000000
--- a/compact_str/src/asserts.rs
+++ /dev/null
@@ -1,42 +0,0 @@
-//! Macros used to statically assert the size different components (e.g. structs).
-//!
-//! These macros were directly copied from the [`static-assertions`](https://github.com/nvzqz/static-assertions-rs)
-//! crate with the following license:
-//!
-//! MIT License
-//!
-//! Copyright (c) 2017 Nikolai Vazquez
-//!
-//! Permission is hereby granted, free of charge, to any person obtaining a copy
-//! of this software and associated documentation files (the "Software"), to deal
-//! in the Software without restriction, including without limitation the rights
-//! to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//! copies of the Software, and to permit persons to whom the Software is
-//! furnished to do so, subject to the following conditions:
-//!
-//! The above copyright notice and this permission notice shall be included in all
-//! copies or substantial portions of the Software.
-//!
-//! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//! IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//! FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//! AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//! LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//! OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-//! SOFTWARE.
-
-macro_rules! assert_size_eq {
-    ($x:ty, $($xs:ty),+ $(,)?) => {
-        const _: fn() = || {
-            $(let _ = ::core::mem::transmute::<$x, $xs>;)+
-        };
-    };
-}
-pub(crate) use assert_size_eq;
-
-macro_rules! assert_size {
-    ($x:ty, $s:expr) => {
-        const _: [u8; ::core::mem::size_of::<$x>()] = [0; $s];
-    };
-}
-pub(crate) use assert_size;
diff --git a/compact_str/src/features/bytes.rs b/compact_str/src/features/bytes.rs
index d0598376..617a5a0a 100644
--- a/compact_str/src/features/bytes.rs
+++ b/compact_str/src/features/bytes.rs
@@ -37,7 +37,7 @@ impl CompactString {
     /// ```
     #[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
     pub fn from_utf8_buf<B: Buf>(buf: &mut B) -> Result<Self, Utf8Error> {
-        Repr::from_utf8_buf(buf).map(|repr| CompactString { repr })
+        Repr::from_utf8_buf(buf).map(CompactString)
     }
 
     /// Converts a buffer of bytes to a [`CompactString`], without checking that the provided buffer
@@ -63,7 +63,7 @@ impl CompactString {
     #[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
     pub unsafe fn from_utf8_buf_unchecked<B: Buf>(buf: &mut B) -> Self {
         let repr = Repr::from_utf8_buf_unchecked(buf);
-        CompactString { repr }
+        CompactString(repr)
     }
 }
 
diff --git a/compact_str/src/lib.rs b/compact_str/src/lib.rs
index 6be14b0d..8b4d4e41 100644
--- a/compact_str/src/lib.rs
+++ b/compact_str/src/lib.rs
@@ -33,7 +33,6 @@ use std::borrow::Cow;
 use std::ffi::OsStr;
 use std::iter::FusedIterator;
 
-mod asserts;
 mod features;
 mod macros;
 mod utility;
@@ -89,9 +88,8 @@ mod tests;
 /// assert_eq!(CompactString::new("houston"), String::from("houston"));
 /// ```
 #[derive(Clone)]
-pub struct CompactString {
-    repr: Repr,
-}
+#[repr(transparent)]
+pub struct CompactString(Repr);
 
 impl CompactString {
     /// Creates a new [`CompactString`] from any type that implements `AsRef<str>`.
@@ -146,9 +144,7 @@ impl CompactString {
     /// ```
     #[inline]
     pub fn new<T: AsRef<str>>(text: T) -> Self {
-        CompactString {
-            repr: Repr::new(text),
-        }
+        CompactString(Repr::new(text.as_ref()))
     }
 
     /// Creates a new inline [`CompactString`] at compile time.
@@ -167,9 +163,7 @@ impl CompactString {
     /// ```
     #[inline]
     pub const fn new_inline(text: &str) -> Self {
-        CompactString {
-            repr: Repr::new_inline(text),
-        }
+        CompactString(Repr::new_inline(text))
     }
 
     /// Creates a new empty [`CompactString`] with the capacity to fit at least `capacity` bytes.
@@ -210,19 +204,20 @@ impl CompactString {
     /// ```
     /// # use compact_str::CompactString;
     /// // If you create a `CompactString` with a capacity greater than
-    /// // `std::mem::size_of::<String>`, it will heap allocated
+    /// // `std::mem::size_of::<String>`, it will heap allocated. For heap
+    /// // allocated strings we have a minimum capacity
+    ///
+    /// const MIN_HEAP_CAPACITY: usize = std::mem::size_of::<usize>() * 4;
     ///
     /// let heap_size = std::mem::size_of::<String>() + 1;
     /// let empty = CompactString::with_capacity(heap_size);
     ///
-    /// assert_eq!(empty.capacity(), heap_size);
+    /// assert_eq!(empty.capacity(), MIN_HEAP_CAPACITY);
     /// assert!(empty.is_heap_allocated());
     /// ```
     #[inline]
     pub fn with_capacity(capacity: usize) -> Self {
-        CompactString {
-            repr: Repr::with_capacity(capacity),
-        }
+        CompactString(Repr::with_capacity(capacity))
     }
 
     /// Convert a slice of bytes into a [`CompactString`].
@@ -254,8 +249,7 @@ impl CompactString {
     /// ```
     #[inline]
     pub fn from_utf8<B: AsRef<[u8]>>(buf: B) -> Result<Self, Utf8Error> {
-        let repr = Repr::from_utf8(buf)?;
-        Ok(CompactString { repr })
+        Repr::from_utf8(buf).map(CompactString)
     }
 
     /// Converts a vector of bytes to a [`CompactString`] without checking that the string contains
@@ -288,8 +282,7 @@ impl CompactString {
     #[inline]
     #[must_use]
     pub unsafe fn from_utf8_unchecked<B: AsRef<[u8]>>(buf: B) -> Self {
-        let repr = Repr::from_utf8_unchecked(buf);
-        CompactString { repr }
+        CompactString(Repr::from_utf8_unchecked(buf))
     }
 
     /// Decode a [`UTF-16`](https://en.wikipedia.org/wiki/UTF-16) slice of bytes into a
@@ -379,7 +372,7 @@ impl CompactString {
     /// ```
     #[inline]
     pub fn len(&self) -> usize {
-        self.repr.len()
+        self.0.len()
     }
 
     /// Returns `true` if the [`CompactString`] has a length of 0, `false` otherwise
@@ -422,7 +415,7 @@ impl CompactString {
     /// ```
     #[inline]
     pub fn capacity(&self) -> usize {
-        self.repr.capacity()
+        self.0.capacity()
     }
 
     /// Ensures that this [`CompactString`]'s capacity is at least `additional` bytes longer than
@@ -450,7 +443,7 @@ impl CompactString {
     /// ```
     #[inline]
     pub fn reserve(&mut self, additional: usize) {
-        self.repr.reserve(additional)
+        self.0.reserve(additional)
     }
 
     /// Returns a string slice containing the entire [`CompactString`].
@@ -464,7 +457,7 @@ impl CompactString {
     /// ```
     #[inline]
     pub fn as_str(&self) -> &str {
-        self.repr.as_str()
+        self.0.as_str()
     }
 
     /// Returns a mutable string slice containing the entire [`CompactString`].
@@ -480,7 +473,7 @@ impl CompactString {
     #[inline]
     pub fn as_mut_str(&mut self) -> &mut str {
         let len = self.len();
-        unsafe { std::str::from_utf8_unchecked_mut(&mut self.repr.as_mut_slice()[..len]) }
+        unsafe { std::str::from_utf8_unchecked_mut(&mut self.0.as_mut_buf()[..len]) }
     }
 
     /// Returns a byte slice of the [`CompactString`]'s contents.
@@ -494,7 +487,7 @@ impl CompactString {
     /// ```
     #[inline]
     pub fn as_bytes(&self) -> &[u8] {
-        &self.repr.as_slice()[..self.len()]
+        &self.0.as_slice()[..self.len()]
     }
 
     // TODO: Implement a `try_as_mut_slice(...)` that will fail if it results in cloning?
@@ -521,7 +514,7 @@ impl CompactString {
     /// ```
     #[inline]
     pub unsafe fn as_mut_bytes(&mut self) -> &mut [u8] {
-        self.repr.as_mut_slice()
+        self.0.as_mut_buf()
     }
 
     /// Appends the given [`char`] to the end of this [`CompactString`].
@@ -557,7 +550,7 @@ impl CompactString {
     /// ```
     #[inline]
     pub fn pop(&mut self) -> Option<char> {
-        self.repr.pop()
+        self.0.pop()
     }
 
     /// Appends a given string slice onto the end of this [`CompactString`]
@@ -573,7 +566,7 @@ impl CompactString {
     /// ```
     #[inline]
     pub fn push_str(&mut self, s: &str) {
-        self.repr.push_str(s)
+        self.0.push_str(s)
     }
 
     /// Removes a [`char`] from this [`CompactString`] at a byte position and returns it.
@@ -653,7 +646,7 @@ impl CompactString {
     /// * The elements at `old_len..new_len` must be initialized
     #[inline]
     pub unsafe fn set_len(&mut self, new_len: usize) {
-        self.repr.set_len(new_len)
+        self.0.set_len(new_len)
     }
 
     /// Returns whether or not the [`CompactString`] is heap allocated.
@@ -676,7 +669,7 @@ impl CompactString {
     /// ```
     #[inline]
     pub fn is_heap_allocated(&self) -> bool {
-        self.repr.is_heap_allocated()
+        self.0.is_heap_allocated()
     }
 
     /// Ensure that the given range is inside the set data, and that no codepoints are split.
@@ -839,13 +832,13 @@ impl CompactString {
     /// Converts a [`CompactString`] to a raw pointer.
     #[inline]
     pub fn as_ptr(&mut self) -> *const u8 {
-        self.repr.as_slice().as_ptr()
+        self.0.as_slice().as_ptr()
     }
 
     /// Converts a mutable [`CompactString`] to a raw pointer.
     #[inline]
     pub fn as_mut_ptr(&mut self) -> *mut u8 {
-        unsafe { self.repr.as_mut_slice().as_mut_ptr() }
+        unsafe { self.0.as_mut_buf().as_mut_ptr() }
     }
 
     /// Insert string character at an index.
@@ -1005,7 +998,7 @@ impl CompactString {
     /// ```
     #[inline]
     pub fn shrink_to(&mut self, min_capacity: usize) {
-        self.repr.shrink_to(min_capacity);
+        self.0.shrink_to(min_capacity);
     }
 
     /// Shrinks the capacity of this [`CompactString`] to match its length.
@@ -1042,7 +1035,7 @@ impl CompactString {
     /// ```
     #[inline]
     pub fn shrink_to_fit(&mut self) {
-        self.repr.shrink_to(0);
+        self.0.shrink_to(0);
     }
 
     /// Retains only the characters specified by the predicate.
@@ -1384,7 +1377,7 @@ impl CompactString {
     /// assert_eq!(s, "Hello world");
     /// ```
     pub fn into_string(self) -> String {
-        self.repr.into_string()
+        self.0.into_string()
     }
 }
 
@@ -1492,14 +1485,15 @@ impl Hash for CompactString {
 
 impl<'a> From<&'a str> for CompactString {
     fn from(s: &'a str) -> Self {
-        CompactString::new(s)
+        let repr = Repr::new(s);
+        CompactString(repr)
     }
 }
 
 impl From<String> for CompactString {
     fn from(s: String) -> Self {
         let repr = Repr::from_string(s);
-        CompactString { repr }
+        CompactString(repr)
     }
 }
 
@@ -1521,7 +1515,7 @@ impl<'a> From<Cow<'a, str>> for CompactString {
 impl From<Box<str>> for CompactString {
     fn from(b: Box<str>) -> Self {
         let repr = Repr::from_box_str(b);
-        CompactString { repr }
+        CompactString(repr)
     }
 }
 
@@ -1532,6 +1526,20 @@ impl From<CompactString> for String {
     }
 }
 
+impl From<CompactString> for Cow<'_, str> {
+    #[inline]
+    fn from(s: CompactString) -> Self {
+        Self::Owned(s.into_string())
+    }
+}
+
+impl<'a> From<&'a CompactString> for Cow<'a, str> {
+    #[inline]
+    fn from(s: &'a CompactString) -> Self {
+        Self::Borrowed(s)
+    }
+}
+
 impl FromStr for CompactString {
     type Err = core::convert::Infallible;
     fn from_str(s: &str) -> Result<CompactString, Self::Err> {
@@ -1554,49 +1562,49 @@ impl fmt::Display for CompactString {
 impl FromIterator<char> for CompactString {
     fn from_iter<T: IntoIterator<Item = char>>(iter: T) -> Self {
         let repr = iter.into_iter().collect();
-        CompactString { repr }
+        CompactString(repr)
     }
 }
 
 impl<'a> FromIterator<&'a char> for CompactString {
     fn from_iter<T: IntoIterator<Item = &'a char>>(iter: T) -> Self {
         let repr = iter.into_iter().collect();
-        CompactString { repr }
+        CompactString(repr)
     }
 }
 
 impl<'a> FromIterator<&'a str> for CompactString {
     fn from_iter<T: IntoIterator<Item = &'a str>>(iter: T) -> Self {
         let repr = iter.into_iter().collect();
-        CompactString { repr }
+        CompactString(repr)
     }
 }
 
 impl FromIterator<Box<str>> for CompactString {
     fn from_iter<T: IntoIterator<Item = Box<str>>>(iter: T) -> Self {
         let repr = iter.into_iter().collect();
-        CompactString { repr }
+        CompactString(repr)
     }
 }
 
 impl<'a> FromIterator<Cow<'a, str>> for CompactString {
     fn from_iter<T: IntoIterator<Item = Cow<'a, str>>>(iter: T) -> Self {
         let repr = iter.into_iter().collect();
-        CompactString { repr }
+        CompactString(repr)
     }
 }
 
 impl FromIterator<String> for CompactString {
     fn from_iter<T: IntoIterator<Item = String>>(iter: T) -> Self {
         let repr = iter.into_iter().collect();
-        CompactString { repr }
+        CompactString(repr)
     }
 }
 
 impl FromIterator<CompactString> for CompactString {
     fn from_iter<T: IntoIterator<Item = CompactString>>(iter: T) -> Self {
         let repr = iter.into_iter().collect();
-        CompactString { repr }
+        CompactString(repr)
     }
 }
 
@@ -1622,25 +1630,25 @@ impl FromIterator<CompactString> for Cow<'_, str> {
 
 impl Extend<char> for CompactString {
     fn extend<T: IntoIterator<Item = char>>(&mut self, iter: T) {
-        self.repr.extend(iter)
+        self.0.extend(iter)
     }
 }
 
 impl<'a> Extend<&'a char> for CompactString {
     fn extend<T: IntoIterator<Item = &'a char>>(&mut self, iter: T) {
-        self.repr.extend(iter)
+        self.0.extend(iter)
     }
 }
 
 impl<'a> Extend<&'a str> for CompactString {
     fn extend<T: IntoIterator<Item = &'a str>>(&mut self, iter: T) {
-        self.repr.extend(iter)
+        self.0.extend(iter)
     }
 }
 
 impl Extend<Box<str>> for CompactString {
     fn extend<T: IntoIterator<Item = Box<str>>>(&mut self, iter: T) {
-        self.repr.extend(iter)
+        self.0.extend(iter)
     }
 }
 
@@ -1652,7 +1660,7 @@ impl<'a> Extend<Cow<'a, str>> for CompactString {
 
 impl Extend<String> for CompactString {
     fn extend<T: IntoIterator<Item = String>>(&mut self, iter: T) {
-        self.repr.extend(iter)
+        self.0.extend(iter)
     }
 }
 
@@ -1821,4 +1829,4 @@ impl DoubleEndedIterator for Drain<'_> {
 
 impl FusedIterator for Drain<'_> {}
 
-crate::asserts::assert_size_eq!(CompactString, String);
+static_assertions::assert_eq_size!(CompactString, String);
diff --git a/compact_str/src/repr/boxed/capacity.rs b/compact_str/src/repr/boxed/capacity.rs
deleted file mode 100644
index 2ec3cbc3..00000000
--- a/compact_str/src/repr/boxed/capacity.rs
+++ /dev/null
@@ -1,166 +0,0 @@
-use crate::repr::HEAP_MASK;
-
-// how many bytes a `usize` occupies
-const USIZE_SIZE: usize = core::mem::size_of::<usize>();
-
-/// Used to generate [`CAPACITY_IS_ON_THE_HEAP`]
-#[allow(non_snake_case)]
-const fn CAP_ON_HEAP_FLAG() -> [u8; USIZE_SIZE] {
-    // all bytes 255, with the last
-    let mut flag = [255; USIZE_SIZE];
-    flag[USIZE_SIZE - 1] = HEAP_MASK;
-    flag
-}
-
-/// State that describes the capacity as being stored on the heap.
-///
-/// All bytes `255`, with the last being [`HEAP_MASK`], using the same amount of bytes as `usize`
-/// Example (64-bit): `[255, 255, 255, 255, 255, 255, 255, 254]`
-const CAPACITY_IS_ON_THE_HEAP: [u8; USIZE_SIZE] = CAP_ON_HEAP_FLAG();
-
-// how many bytes we can use for capacity
-const SPACE_FOR_CAPACITY: usize = USIZE_SIZE - 1;
-// the maximum value we're able to store, e.g. on 64-bit arch this is 2^56 - 2
-//
-// note: Preferably we'd used usize.pow(..) here, but that's not a `const fn`, so we need to use
-// bitshift operators, and there's a lint against using them in this pattern, which IMO isn't a
-// great lint
-#[allow(clippy::precedence)]
-pub const MAX_VALUE: usize = (1 << SPACE_FOR_CAPACITY * 8) - 2;
-
-/// An integer type that uses `core::mem::size_of::<usize>() - 1` bytes to store the capacity of
-/// a heap buffer.
-///
-/// Assumming a 64-bit arch, a [`super::BoxString`] uses 8 bytes for a pointer, 8 bytes for a
-/// length, and then needs 1 byte for a discriminant. We need to store the capacity somewhere, and
-/// we could store it on the heap, but we also have 7 unused bytes. [`Capacity`] handles storing a
-/// value in these 7 bytes, returning an error if it's not possible, at which point we'll store the
-/// capacity on the heap.
-///
-/// # Max Values
-/// * __64-bit:__ `(2 ^ (7 * 8)) - 2 = 72_057_594_037_927_934 ~= 64 petabytes`
-/// * __32-bit:__ `(2 ^ (3 * 8)) - 2 = 16_777_214             ~= 16 megabytes`
-///
-/// Practically speaking, on a 64-bit architecture we'll never need to store the capacity on the
-/// heap, because with it's impossible to create a string that is 64 petabytes or larger. But for
-/// 32-bit architectures we need to be able to store a capacity larger than 16 megabytes, since a
-/// string larger than 16 megabytes probably isn't that uncommon.
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub struct Capacity {
-    _buf: [u8; USIZE_SIZE],
-}
-
-impl Capacity {
-    #[inline]
-    pub const fn new(capacity: usize) -> Result<Self, Self> {
-        if capacity > MAX_VALUE {
-            // if we need the last byte to encode this capacity then we need to put the capacity on
-            // the heap. return an Error so `BoxString` can do the right thing
-            Err(Capacity {
-                _buf: CAPACITY_IS_ON_THE_HEAP,
-            })
-        } else {
-            let mut bytes = capacity.to_le_bytes();
-            // otherwise, we can store this capacity inline! Set the last byte to be our `HEAP_MASK`
-            // for our discriminant, using the leading bytes to store the actual value
-            bytes[core::mem::size_of::<usize>() - 1] = HEAP_MASK;
-            Ok(Capacity { _buf: bytes })
-        }
-    }
-
-    #[inline]
-    pub fn as_usize(&self) -> Result<usize, ()> {
-        if self._buf == CAPACITY_IS_ON_THE_HEAP {
-            Err(())
-        } else {
-            let mut usize_buf = [0u8; USIZE_SIZE];
-            unsafe {
-                core::ptr::copy_nonoverlapping(
-                    self._buf.as_ptr(),
-                    usize_buf.as_mut_ptr(),
-                    SPACE_FOR_CAPACITY,
-                );
-            }
-            Ok(usize::from_le_bytes(usize_buf))
-        }
-    }
-
-    #[inline(always)]
-    pub fn is_heap(&self) -> bool {
-        self._buf == CAPACITY_IS_ON_THE_HEAP
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use rayon::prelude::*;
-
-    use super::Capacity;
-
-    #[test]
-    fn test_zero_roundtrips() {
-        let og = 0;
-        let cap = Capacity::new(og).unwrap();
-        let after = cap.as_usize().unwrap();
-
-        assert_eq!(og, after);
-    }
-
-    #[test]
-    fn test_max_value() {
-        let available_bytes = (core::mem::size_of::<usize>() - 1) as u32;
-        let max_value = 2usize.pow(available_bytes * 8) - 2;
-
-        #[cfg(target_pointer_width = "64")]
-        assert_eq!(max_value, 72057594037927934);
-        #[cfg(target_pointer_width = "32")]
-        assert_eq!(max_value, 16777214);
-
-        let cap = Capacity::new(max_value).unwrap();
-        let after = cap.as_usize().unwrap();
-
-        assert_eq!(max_value, after);
-    }
-
-    #[test]
-    fn test_first_invalid_value() {
-        let available_bytes = (core::mem::size_of::<usize>() - 1) as u32;
-        let first_invalid = 2usize.pow(available_bytes * 8) - 1;
-
-        #[cfg(target_pointer_width = "64")]
-        assert_eq!(first_invalid, 72057594037927935);
-        #[cfg(target_pointer_width = "32")]
-        assert_eq!(first_invalid, 16777215);
-
-        assert!(Capacity::new(first_invalid).is_err());
-    }
-
-    #[test]
-    fn test_usize_max_fails() {
-        let og = usize::MAX;
-        assert!(Capacity::new(og).is_err());
-    }
-
-    #[test]
-    #[cfg_attr(miri, ignore)]
-    fn test_all_valid_32bit_values() {
-        #[cfg(target_pointer_width = "32")]
-        assert_eq!(16_777_214, super::MAX_VALUE);
-
-        (0..=16_777_214)
-            .into_par_iter()
-            .for_each(|i| match Capacity::new(i) {
-                Ok(cap) => match cap.as_usize() {
-                    Ok(val) => assert_eq!(val, i, "value roundtriped to wrong value?"),
-                    Err(_) => panic!("value converted, but failed to roundtrip! val: {}", i),
-                },
-                Err(_) => panic!("failed to convert {}", i),
-            });
-
-        // one above the 32-bit max value
-        #[cfg(target_pointer_width = "32")]
-        assert!(Capacity::new(16_777_215).is_err());
-    }
-}
-
-crate::asserts::assert_size_eq!(Capacity, usize);
diff --git a/compact_str/src/repr/boxed/inner.rs b/compact_str/src/repr/boxed/inner.rs
deleted file mode 100644
index ee4e8f0a..00000000
--- a/compact_str/src/repr/boxed/inner.rs
+++ /dev/null
@@ -1,94 +0,0 @@
-const UNKNOWN: usize = 0;
-pub type StrBuffer = [u8; UNKNOWN];
-
-pub mod heap_capacity {
-    use core::ptr;
-    use std::alloc;
-
-    use super::StrBuffer;
-
-    pub fn alloc(capacity: usize) -> ptr::NonNull<u8> {
-        let layout = layout(capacity);
-        debug_assert!(layout.size() > 0);
-
-        // SAFETY: `alloc(...)` has undefined behavior if the layout is zero-sized. We know the
-        // layout can't be zero-sized though because we're always at least allocating one `usize`
-        let raw_ptr = unsafe { alloc::alloc(layout) };
-
-        // Check to make sure our pointer is non-null, some allocators return null pointers instead
-        // of panicking
-        match ptr::NonNull::new(raw_ptr) {
-            Some(ptr) => ptr,
-            None => alloc::handle_alloc_error(layout),
-        }
-    }
-
-    pub unsafe fn dealloc(ptr: ptr::NonNull<u8>, capacity: usize) {
-        let layout = layout(capacity);
-
-        // SAFETY: TODO
-        alloc::dealloc(ptr.as_ptr(), layout);
-    }
-
-    #[repr(C)]
-    struct BoxStringInnerHeapCapacity {
-        capacity: usize,
-        buffer: StrBuffer,
-    }
-
-    pub fn layout(capacity: usize) -> alloc::Layout {
-        let buffer_layout = alloc::Layout::array::<u8>(capacity).expect("valid capacity");
-        alloc::Layout::new::<BoxStringInnerHeapCapacity>()
-            .extend(buffer_layout)
-            .expect("valid layout")
-            .0
-            .pad_to_align()
-    }
-}
-
-pub mod inline_capacity {
-    use core::ptr;
-    use std::alloc;
-
-    use super::StrBuffer;
-
-    /// # Safety
-    /// * `capacity` must be > 0
-    pub unsafe fn alloc(capacity: usize) -> ptr::NonNull<u8> {
-        let layout = layout(capacity);
-        debug_assert!(layout.size() > 0);
-
-        // SAFETY: `alloc(...)` has undefined behavior if the layout is zero-sized. We specify that
-        // `capacity` must be > 0 as a constraint to uphold the safety of this method. If capacity
-        // is greater than 0, then our layout will be non-zero-sized.
-        let raw_ptr = alloc::alloc(layout);
-
-        // Check to make sure our pointer is non-null, some allocators return null pointers instead
-        // of panicking
-        match ptr::NonNull::new(raw_ptr) {
-            Some(ptr) => ptr,
-            None => alloc::handle_alloc_error(layout),
-        }
-    }
-
-    pub unsafe fn dealloc(ptr: ptr::NonNull<u8>, capacity: usize) {
-        let layout = layout(capacity);
-
-        // SAFETY: TODO
-        alloc::dealloc(ptr.as_ptr(), layout);
-    }
-
-    #[repr(C)]
-    struct BoxStringInnerInlineCapacity {
-        buffer: StrBuffer,
-    }
-
-    pub fn layout(capacity: usize) -> alloc::Layout {
-        let buffer_layout = alloc::Layout::array::<u8>(capacity).expect("valid capacity");
-        alloc::Layout::new::<BoxStringInnerInlineCapacity>()
-            .extend(buffer_layout)
-            .expect("valid layout")
-            .0
-            .pad_to_align()
-    }
-}
diff --git a/compact_str/src/repr/boxed/mod.rs b/compact_str/src/repr/boxed/mod.rs
deleted file mode 100644
index 803d022c..00000000
--- a/compact_str/src/repr/boxed/mod.rs
+++ /dev/null
@@ -1,887 +0,0 @@
-use core::iter::Extend;
-use core::mem::ManuallyDrop;
-use core::{
-    fmt,
-    ptr,
-    slice,
-    str,
-};
-use std::alloc;
-use std::ptr::NonNull;
-
-mod capacity;
-use capacity::Capacity;
-
-mod inner;
-
-const MIN_SIZE: usize = core::mem::size_of::<usize>() / 2;
-
-/// [`BoxString`] grows at an amortized rates of 1.5x
-///
-/// Note: this is different than [`std::string::String`], which grows at a rate of 2x. It's debated
-/// which is better, for now we'll stick with a rate of 1.5x
-///
-/// TODO: Handle overflows in the case of __very__ large Strings
-#[inline(always)]
-fn amortized_growth(cur_len: usize, additional: usize) -> usize {
-    let required = cur_len + additional;
-    let amortized = 3 * cur_len / 2;
-    core::cmp::max(amortized, required)
-}
-
-#[repr(C)]
-pub struct BoxString {
-    ptr: ptr::NonNull<u8>,
-    len: usize,
-    cap: Capacity,
-}
-unsafe impl Sync for BoxString {}
-unsafe impl Send for BoxString {}
-
-impl BoxString {
-    #[inline]
-    pub fn new(text: &str) -> Self {
-        let len = text.len();
-
-        // Always allocate at least a few bytes
-        //
-        // Note: practically we should never try to create an empty `BoxString`, since we inline
-        // short strings
-        let capacity = core::cmp::max(len, MIN_SIZE);
-
-        // SAFETY: `Self::alloc_ptr(...)` requires that capacity is non-zero. Above we set capacity
-        // to be at least size_of::<usize>, so we know it'll be non-zero.
-        let (cap, ptr) = unsafe { BoxString::alloc_ptr(capacity) };
-
-        let write_ptr = if !cap.is_heap() {
-            ptr.as_ptr()
-        } else {
-            unsafe { ptr.as_ptr().add(core::mem::size_of::<usize>()) }
-        };
-
-        // SAFETY: We know both `src` and `dest` are valid for respectively reads and writes of
-        // length `len` because `len` comes from `src`, and `dest` was allocated to be at least that
-        // length. We also know they're non-overlapping because `dest` is newly allocated
-        unsafe { write_ptr.copy_from_nonoverlapping(text.as_ptr(), len) };
-
-        BoxString { len, ptr, cap }
-    }
-
-    #[inline]
-    pub fn with_capacity(capacity: usize) -> Self {
-        let len = 0;
-
-        // Always allocate at least a few bytes
-        //
-        // Note: practically we should never try to create an empty `BoxString`, since we inline
-        // short strings
-        let capacity = core::cmp::max(capacity, MIN_SIZE);
-
-        // SAFETY: `Self::alloc_ptr(...)` requires that capacity is non-zero. Above we set capacity
-        // to be at least size_of::<usize>, so we know it'll be non-zero.
-        let (cap, ptr) = unsafe { BoxString::alloc_ptr(capacity) };
-
-        BoxString { len, ptr, cap }
-    }
-
-    #[inline(always)]
-    unsafe fn alloc_ptr(capacity: usize) -> (Capacity, ptr::NonNull<u8>) {
-        #[cold]
-        unsafe fn alloc_ptr_heap(capacity: usize, cap: Capacity) -> (Capacity, ptr::NonNull<u8>) {
-            let ptr = inner::heap_capacity::alloc(capacity);
-            // write our capacity onto the heap
-            core::ptr::copy_nonoverlapping(
-                capacity.to_le_bytes().as_ptr(),
-                ptr.as_ptr(),
-                core::mem::size_of::<usize>(),
-            );
-            (cap, ptr)
-        }
-
-        let (cap, ptr) = match Capacity::new(capacity) {
-            Ok(cap) => {
-                debug_assert!(capacity <= capacity::MAX_VALUE);
-                let ptr = inner::inline_capacity::alloc(capacity);
-                (cap, ptr)
-            }
-            Err(cap) => alloc_ptr_heap(capacity, cap),
-        };
-
-        (cap, ptr)
-    }
-
-    #[inline]
-    pub fn with_additional(text: &str, additional: usize) -> Self {
-        let len = text.len();
-        let new_capacity = amortized_growth(len, additional);
-
-        // TODO: Handle overflows in the case of __very__ large Strings
-        debug_assert!(new_capacity >= len);
-
-        // Create the `BoxString` with our determined capacity
-        let mut new = BoxString::with_capacity(new_capacity);
-
-        // SAFETY: We're writing a &str which is valid UTF-8
-        let buffer = unsafe { new.as_mut_slice() };
-        buffer[..len].copy_from_slice(text.as_bytes());
-
-        // SAFETY: We just wrote `len` bytes into our buffer
-        unsafe { new.set_len(len) };
-
-        new
-    }
-
-    #[inline]
-    pub fn from_string(s: String) -> Self {
-        match Capacity::new(s.capacity()) {
-            // Note: We should never hit this case when using BoxString with CompactString
-            Ok(_) if s.capacity() == 0 => BoxString::new(""),
-            Ok(cap) => {
-                // Don't drop `s` to avoid a double free
-                let mut s = ManuallyDrop::new(s.into_bytes());
-                let len = s.len();
-                let raw_ptr = s.as_mut_ptr();
-
-                let ptr = ptr::NonNull::new(raw_ptr).expect("string with capacity has null ptr?");
-                // create a new BoxString with our parts!
-                BoxString { len, ptr, cap }
-            }
-            Err(_) => BoxString::new(s.as_str()),
-        }
-    }
-
-    #[inline]
-    pub fn into_string(self) -> String {
-        #[cold]
-        fn into_string_heap(this: BoxString) -> String {
-            String::from(this.as_str())
-        }
-
-        match self.cap.as_usize() {
-            Ok(cap) => {
-                // Ensure that we don't free the data we are transferring the buffer to `String`
-                let this = ManuallyDrop::new(self);
-
-                // SAFETY:
-                // * The memory in `ptr` was previously allocated by the same allocator the standard
-                //   library uses, with a required alignment of exactly 1.
-                // * `length` is less than or equal to capacity, due to internal invaraints.
-                // * `capacity` is correctly maintained internally.
-                // * `BoxString` only ever contains valid UTF-8.
-                unsafe { String::from_raw_parts(this.ptr.as_ptr(), this.len, cap) }
-            }
-            Err(_) => into_string_heap(self),
-        }
-    }
-
-    #[inline]
-    pub fn from_box_str(b: Box<str>) -> Self {
-        match Capacity::new(b.len()) {
-            // Note: We should never hit this case when using BoxString with CompactString
-            Ok(_) if b.len() == 0 => BoxString::new(""),
-            Ok(cap) => {
-                let len = b.len();
-                // Don't drop the box here
-                let raw_ptr = Box::into_raw(b).cast::<u8>();
-
-                let ptr = ptr::NonNull::new(raw_ptr).expect("string with capacity has null ptr?");
-                // create a new BoxString with our parts!
-                BoxString { len, ptr, cap }
-            }
-            Err(_) => BoxString::new(&b),
-        }
-    }
-
-    /// Reserve space for at least `additional` bytes
-    #[inline]
-    pub fn reserve(&mut self, additional: usize) {
-        // We need at least this much space
-        let len = self.len();
-        let required = len + additional;
-
-        // We have enough space, so there is no work to do
-        if self.capacity() >= required {
-            return;
-        }
-
-        let new_capacity = amortized_growth(len, additional);
-
-        // try to realloc, creating a new BoxString on failure
-        if self.realloc(new_capacity).is_err() {
-            // We failed to realloc, so create a new BoxString
-            let new = BoxString::with_additional(self.as_str(), additional);
-            // Set our new BoxString as self
-            *self = new;
-        }
-    }
-
-    #[inline]
-    pub const fn len(&self) -> usize {
-        self.len
-    }
-
-    #[inline]
-    pub fn capacity(&self) -> usize {
-        #[cold]
-        fn capacity_heap(this: &BoxString) -> usize {
-            let mut usize_buf = [0u8; core::mem::size_of::<usize>()];
-            // copy bytes from the heap into our buffer
-            unsafe {
-                core::ptr::copy_nonoverlapping(
-                    this.ptr.as_ptr() as *const u8,
-                    usize_buf.as_mut_ptr(),
-                    core::mem::size_of::<usize>(),
-                );
-            };
-            // interpret those bytes as a usize
-            usize::from_le_bytes(usize_buf)
-        }
-
-        match self.cap.as_usize() {
-            // capacity is on the stack, just return it!
-            Ok(cap) => cap,
-            // capacity is on the heap, we need to read it back
-            Err(_) => capacity_heap(self),
-        }
-    }
-
-    #[inline]
-    pub fn push(&mut self, ch: char) {
-        let len = self.len();
-        let char_len = ch.len_utf8();
-
-        // Reserve at least enough space for the new char
-        self.reserve(char_len);
-
-        // SAFETY: We're writing a char into the slice, which is valid UTF-8
-        let slice = unsafe { self.as_mut_slice() };
-
-        // Write our char into the slice
-        ch.encode_utf8(&mut slice[len..]);
-
-        // Increment our length
-        //
-        // SAFETY: We just wrote `char_len` bytes into the buffer, so we know this new length is
-        // valid
-        unsafe { self.set_len(len + char_len) };
-    }
-
-    #[inline]
-    pub fn push_str(&mut self, s: &str) {
-        let len = self.len();
-        let str_len = s.len();
-
-        // Reserve at least enough space for the new str
-        self.reserve(str_len);
-
-        // SAFETY: We're writing a &str into the slice, which is valid UTF-8
-        let slice = unsafe { self.as_mut_slice() };
-        let buffer = &mut slice[len..len + str_len];
-
-        debug_assert_eq!(buffer.len(), s.as_bytes().len());
-
-        // Copy the string into our buffer
-        buffer.copy_from_slice(s.as_bytes());
-        // Incrament the length of our string
-        unsafe { self.set_len(len + str_len) };
-    }
-
-    #[inline]
-    pub fn as_str(&self) -> &str {
-        // SAFETY: The only way you can construct an `BoxString` is via a `&str` so it must be valid
-        // UTF-8, or the caller has manually made those guarantees
-        unsafe { str::from_utf8_unchecked(self.as_slice()) }
-    }
-
-    #[inline(always)]
-    pub fn as_slice(&self) -> &[u8] {
-        &self.as_buffer()[..self.len]
-    }
-
-    /// Returns a mutable reference to the underlying buffer of bytes
-    ///
-    /// # Safety:
-    /// * The caller must guarantee any modifications made to the buffer are valid UTF-8
-    #[inline]
-    pub unsafe fn as_mut_slice(&mut self) -> &mut [u8] {
-        self.as_mut_buffer()
-    }
-
-    #[inline]
-    pub unsafe fn set_len(&mut self, length: usize) {
-        self.len = length;
-    }
-
-    #[inline]
-    fn as_buffer(&self) -> &[u8] {
-        #[cold]
-        fn as_buffer_heap(this: &BoxString) -> &[u8] {
-            // read our first few bytes to get our capacity
-            let mut usize_buf = [0u8; core::mem::size_of::<usize>()];
-            unsafe {
-                core::ptr::copy_nonoverlapping(
-                    this.ptr.as_ptr() as *const u8,
-                    usize_buf.as_mut_ptr(),
-                    core::mem::size_of::<usize>(),
-                );
-            };
-            let cap = usize::from_le_bytes(usize_buf);
-
-            // read `cap` bytes from our buffer, starting at an offset
-            let buf_start = unsafe { this.ptr.as_ptr().add(core::mem::size_of::<usize>()) };
-            // SAFETY: Since we have an instance of `BoxStringInner` so we know the buffer is still
-            // valid. Also since we're on a 64-bit arch, it's practically impossible for our
-            // capacity to be stored on the heap
-            unsafe { slice::from_raw_parts(buf_start, cap) }
-        }
-
-        match self.cap.as_usize() {
-            // capacity is on the stack, so read the entire buffer!
-            Ok(cap) => unsafe { slice::from_raw_parts(self.ptr.as_ptr(), cap) },
-            // capacity is on the heap, we need to read the capacity, and then read the buffer
-            // starting from an offset
-            Err(_) => as_buffer_heap(self),
-        }
-    }
-
-    #[inline]
-    unsafe fn as_mut_buffer(&mut self) -> &mut [u8] {
-        #[cold]
-        unsafe fn as_mut_buffer_heap(this: &mut BoxString) -> &mut [u8] {
-            // read our first few bytes to get our capacity
-            let mut usize_buf = [0u8; core::mem::size_of::<usize>()];
-            core::ptr::copy_nonoverlapping(
-                this.ptr.as_ptr() as *const u8,
-                usize_buf.as_mut_ptr(),
-                core::mem::size_of::<usize>(),
-            );
-            let cap = usize::from_le_bytes(usize_buf);
-
-            // read `cap` bytes from our buffer, starting at an offset
-            let buf_start = this.ptr.as_ptr().add(core::mem::size_of::<usize>());
-            // SAFETY: Since we have an instance of `BoxStringInner` so we know the buffer is still
-            // valid. Also since we're on a 64-bit arch, it's practically impossible for our
-            // capacity to be stored on the heap
-            slice::from_raw_parts_mut(buf_start, cap)
-        }
-
-        match self.cap.as_usize() {
-            // capacity is on the stack, so read the entire buffer!
-            Ok(cap) => slice::from_raw_parts_mut(self.ptr.as_ptr(), cap),
-            // capacity is on the heap, we need to read the capacity, and then read the buffer
-            // starting from an offset
-            Err(_) => as_mut_buffer_heap(self),
-        }
-    }
-
-    #[inline(never)]
-    unsafe fn drop_inner(&mut self) {
-        #[cold]
-        unsafe fn drop_heap(this: &mut BoxString) {
-            // read our first few bytes to get our capacity
-            let mut usize_buf = [0u8; core::mem::size_of::<usize>()];
-            core::ptr::copy_nonoverlapping(
-                this.ptr.as_ptr() as *const u8,
-                usize_buf.as_mut_ptr(),
-                core::mem::size_of::<usize>(),
-            );
-            let cap = usize::from_le_bytes(usize_buf);
-
-            inner::heap_capacity::dealloc(this.ptr, cap)
-        }
-
-        match self.cap.as_usize() {
-            Ok(cap) => inner::inline_capacity::dealloc(self.ptr, cap),
-            Err(_) => drop_heap(self),
-        }
-    }
-
-    /// Tries to reallocate the buffer, and sets the new capacity on success.
-    ///
-    /// Returns the new capacity as `Ok(…)` if the string was reallocated.
-    /// Or the old capacity as `Err(…)` if the string could not be reallocated.
-    pub fn realloc(&mut self, new_capacity: usize) -> Result<usize, ()> {
-        // can't reallocate a BoxString to a size less than the current length
-        if new_capacity < self.len {
-            return Err(());
-        }
-
-        let cur_cap = self.cap.as_usize();
-        let new_cap = Capacity::new(new_capacity);
-
-        let (new_cap, new_ptr) = match (cur_cap, new_cap) {
-            // current capacity is the same as new, no realloc needed!
-            (Ok(cur), Ok(_)) if cur == new_capacity => {
-                return Ok(new_capacity);
-            }
-            // both current and new capacity can be stored inline
-            (Ok(cur), Ok(new_cap)) => {
-                let cur_layout = inner::inline_capacity::layout(cur);
-                let new_size = inner::inline_capacity::layout(new_capacity).size();
-
-                // attempt to reallocate, returning an error if we failed
-                match NonNull::new(unsafe {
-                    alloc::realloc(self.ptr.as_ptr(), cur_layout, new_size)
-                }) {
-                    Some(ptr) => (new_cap, ptr),
-                    None => return Err(()),
-                }
-            }
-            // capacity is currently on the heap, and needs to stay on the heap
-            (Err(_), Err(new_cap)) => {
-                let cur_layout = inner::heap_capacity::layout(self.capacity());
-                let new_size = inner::heap_capacity::layout(new_capacity).size();
-
-                // attempt to reallocate, returning an error if we failed
-                let ptr = match NonNull::new(unsafe {
-                    alloc::realloc(self.ptr.as_ptr(), cur_layout, new_size)
-                }) {
-                    Some(ptr) => ptr,
-                    None => return Err(()),
-                };
-
-                // our allocation succeeded! we need to write the new cap to the heap
-                unsafe {
-                    core::ptr::copy_nonoverlapping(
-                        new_capacity.to_le_bytes().as_ptr(),
-                        ptr.as_ptr(),
-                        core::mem::size_of::<usize>(),
-                    )
-                };
-
-                (new_cap, ptr)
-            }
-            // capacity is currently inline or on the heap, but needs to move, can't realloc!
-            (Ok(_), Err(_)) | (Err(_), Ok(_)) => {
-                return Err(());
-            }
-        };
-
-        // set our new pointer and new capacity
-        self.ptr = new_ptr;
-        self.cap = new_cap;
-
-        Ok(new_capacity)
-    }
-}
-
-impl Clone for BoxString {
-    fn clone(&self) -> Self {
-        // Create a new BoxString
-        let len = self.len();
-        let mut new = Self::with_capacity(self.capacity());
-
-        // Write the existing String into it
-        // SAFETY: We're writing a &str which we know is valid UTF-8
-        let buffer = unsafe { new.as_mut_slice() };
-        buffer[..len].copy_from_slice(self.as_slice());
-        // SAFETY: We just wrote `len` bytes into our buffer
-        unsafe { new.set_len(len) };
-
-        new
-    }
-}
-
-impl fmt::Debug for BoxString {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Debug::fmt(self.as_str(), f)
-    }
-}
-
-impl From<&str> for BoxString {
-    #[inline]
-    fn from(text: &str) -> Self {
-        BoxString::new(text)
-    }
-}
-
-impl Drop for BoxString {
-    fn drop(&mut self) {
-        unsafe { self.drop_inner() }
-    }
-}
-
-impl Extend<char> for BoxString {
-    #[inline]
-    fn extend<T: IntoIterator<Item = char>>(&mut self, iter: T) {
-        let iterator = iter.into_iter();
-        let (lower_bound, _) = iterator.size_hint();
-        self.reserve(lower_bound);
-        iterator.for_each(|c| self.push(c));
-    }
-}
-
-impl<'c> Extend<&'c char> for BoxString {
-    #[inline]
-    fn extend<T: IntoIterator<Item = &'c char>>(&mut self, iter: T) {
-        self.extend(iter.into_iter().copied());
-    }
-}
-
-impl<'s> Extend<&'s str> for BoxString {
-    #[inline]
-    fn extend<T: IntoIterator<Item = &'s str>>(&mut self, iter: T) {
-        iter.into_iter().for_each(|s| self.push_str(s));
-    }
-}
-
-impl Extend<Box<str>> for BoxString {
-    #[inline]
-    fn extend<T: IntoIterator<Item = Box<str>>>(&mut self, iter: T) {
-        iter.into_iter().for_each(|s| self.push_str(&s));
-    }
-}
-
-impl Extend<String> for BoxString {
-    #[inline]
-    fn extend<T: IntoIterator<Item = String>>(&mut self, iter: T) {
-        iter.into_iter().for_each(move |s| self.push_str(&s));
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use proptest::prelude::*;
-    use test_strategy::proptest;
-
-    use super::BoxString;
-    use crate::tests::rand_unicode;
-
-    const SIXTEEN_MB: usize = 16 * 1024 * 1024;
-
-    #[test]
-    fn test_sanity() {
-        let example = "hello world!";
-        let box_str = BoxString::from(example);
-
-        assert_eq!(box_str.as_str(), example);
-        assert_eq!(box_str.len(), example.len());
-    }
-
-    #[test]
-    fn test_empty() {
-        let box_string = BoxString::new("");
-        assert_eq!(box_string.as_str(), "");
-    }
-
-    #[test]
-    fn test_push() {
-        let example = "hello world";
-        let mut boxed = BoxString::from(example);
-
-        boxed.push('!');
-        assert_eq!(boxed.as_str(), "hello world!");
-        assert_eq!(boxed.len(), 12);
-    }
-
-    #[test]
-    fn test_push_str() {
-        let example = "hello";
-        let mut boxed = BoxString::from(example);
-
-        boxed.push_str(" world!");
-        assert_eq!(boxed.as_str(), "hello world!");
-        assert_eq!(boxed.len(), 12);
-        assert_eq!(boxed.capacity(), 12);
-    }
-
-    #[test]
-    fn test_clone_and_drop() {
-        let example = "nyc";
-        let one = BoxString::from(example);
-        let two = one.clone();
-
-        assert_eq!(one.as_str(), example);
-        drop(one);
-        assert_eq!(two.as_str(), example);
-    }
-
-    #[test]
-    fn test_box_string_capacity() {
-        let example = "hello";
-        let mut boxed = BoxString::from(example);
-
-        // Starts with a capacity equal to length
-        assert_eq!(boxed.capacity(), 5);
-
-        boxed.push(' ');
-        // Immediate reallocate to 1.5 * capacity
-        assert_eq!(boxed.len(), 6);
-        assert_eq!(boxed.capacity(), 7);
-
-        boxed.push('w');
-        boxed.push('o');
-        // Right now our len and cap are both 7, pushing 'o' should cause us to resize
-        assert_eq!(boxed.len(), 8);
-        assert_eq!(boxed.capacity(), 10);
-
-        boxed.push('r');
-        boxed.push('l');
-        boxed.push('d');
-        assert_eq!(boxed.len(), 11);
-        assert_eq!(boxed.capacity(), 15);
-
-        assert_eq!(boxed.as_str(), "hello world");
-    }
-
-    #[test]
-    fn test_string_capacity() {
-        let example = "hello";
-        let mut std_string = String::from(example);
-
-        // `std::String` starts with capacity equal to length
-        assert_eq!(std_string.capacity(), 5);
-
-        // then doubles when re-allocating
-        std_string.push(' ');
-        assert_eq!(std_string.capacity(), 10);
-
-        std_string.push('w');
-        std_string.push('o');
-        std_string.push('r');
-        std_string.push('l');
-
-        // after pushing an 11th element, we double capacity again
-        std_string.push('d');
-        assert_eq!(std_string.capacity(), 20);
-
-        std_string.push('!');
-    }
-
-    #[test]
-    fn test_from_string_parts() {
-        let s = String::from("hello world!");
-        let box_string = BoxString::from_string(s.clone());
-
-        assert_eq!(s.as_str(), box_string.as_str());
-    }
-
-    #[test]
-    fn test_from_string_parts_empty() {
-        let s = String::from("");
-        let box_string = BoxString::from_string(s.clone());
-
-        assert_eq!(s.as_str(), box_string.as_str());
-    }
-
-    #[test]
-    fn test_32_bit_max_inline_cap() {
-        // 65 is the ASCII value of 'A'
-        // `SIXTEEN_MB - 2` is the max value we can store for capacity inline, when on 32-bit archs
-        let word_buf = vec![b'A'; SIXTEEN_MB - 2];
-        // SAFETY: We've just created the vector above, and it contains only ASCII characters.
-        // This speeds up `miri` runs significantly.
-        let string = unsafe { String::from_utf8_unchecked(word_buf) };
-
-        let box_string = BoxString::new(&string);
-
-        // make sure the capacity was able to be stored inline
-        assert_eq!(box_string.cap.as_usize(), Ok(SIXTEEN_MB - 2));
-        // assert the strings are equal
-        assert_eq!(&string, box_string.as_str());
-    }
-
-    #[test]
-    fn test_32_bit_max_inline_cap_with_modification() {
-        // 65 is the ASCII value of 'A'
-        // `SIXTEEN_MB - 2` is the max value we can store for capacity inline, when on 32-bit archs
-        let word_buf = vec![b'A'; SIXTEEN_MB - 2];
-        // SAFETY: We've just created the vector above, and it contains only ASCII characters.
-        // This speeds up `miri` runs significantly.
-        let string = unsafe { String::from_utf8_unchecked(word_buf) };
-
-        let mut box_string = BoxString::new(&string);
-
-        // make sure the capacity was able to be stored inline
-        assert_eq!(box_string.cap.as_usize(), Ok(SIXTEEN_MB - 2));
-        // assert the strings are equal
-        assert_eq!(&string, box_string.as_str());
-
-        // push a single character
-        box_string.push('!');
-        // assert the string is still correct
-        assert_eq!(&format!("{}!", string), box_string.as_str());
-
-        cfg_if::cfg_if! {
-            if #[cfg(target_pointer_width = "64")] {
-                // on 64-bit archs it's still inlined
-                assert!(box_string.cap.as_usize().is_ok());
-            } else if #[cfg(target_pointer_width = "32")] {
-                // on 32-bit archs the capacity will be stored on the heap
-                assert!(box_string.cap.as_usize().is_err());
-            } else {
-                compile_error!("Unsupported target_pointer_width");
-            }
-        }
-
-        // push a string
-        box_string.push_str("hello!");
-
-        cfg_if::cfg_if! {
-            if #[cfg(target_pointer_width = "64")] {
-                // on 64-bit archs it's still inlined
-                assert!(box_string.cap.as_usize().is_ok());
-            } else if #[cfg(target_pointer_width = "32")] {
-                // on 32-bit archs the capacity will still be stored on the heap, since the capacity
-                // hasn't changed
-                assert!(box_string.cap.as_usize().is_err());
-            } else {
-                compile_error!("Unsupported target_pointer_width");
-            }
-        }
-
-        // assert the string is still correct
-        assert_eq!(&format!("{}!hello!", string), box_string.as_str());
-    }
-
-    #[test]
-    fn test_32_bit_min_heap_cap() {
-        // 65 is the ASCII value of 'A'
-        // `SIXTEEN_MB - 1` is the min value for capacity that gets stored on the heap
-        let word_buf = vec![b'A'; SIXTEEN_MB - 1];
-        // SAFETY: We've just created the vector above, and it contains only ASCII characters.
-        // This speeds up `miri` runs significantly.
-        let string = unsafe { String::from_utf8_unchecked(word_buf) };
-
-        let mut box_string = BoxString::new(&string);
-
-        cfg_if::cfg_if! {
-            if #[cfg(target_pointer_width = "64")] {
-                // on 64-bit archs it's still inlined
-                assert_eq!(box_string.cap.as_usize(), Ok(SIXTEEN_MB - 1));
-            } else if #[cfg(target_pointer_width = "32")] {
-                // on 32-bit archs the capacity will be stored on the heap
-                assert!(box_string.cap.as_usize().is_err());
-            } else {
-                compile_error!("Unsupported target_pointer_width");
-            }
-        }
-
-        // assert the strings are equal
-        assert_eq!(&string, box_string.as_str());
-
-        // push a single character
-        box_string.push('!');
-        // assert the string is still correct
-        assert_eq!(&format!("{}!", string), box_string.as_str());
-
-        cfg_if::cfg_if! {
-            if #[cfg(target_pointer_width = "64")] {
-                // on 64-bit archs it's still inlined
-                assert!(box_string.cap.as_usize().is_ok());
-            } else if #[cfg(target_pointer_width = "32")] {
-                // on 32-bit archs the capacity will be stored on the heap
-                assert!(box_string.cap.as_usize().is_err());
-            } else {
-                compile_error!("Unsupported target_pointer_width");
-            }
-        }
-
-        // push a string
-        box_string.push_str("hello!");
-
-        cfg_if::cfg_if! {
-            if #[cfg(target_pointer_width = "64")] {
-                // on 64-bit archs it's still inlined
-                assert!(box_string.cap.as_usize().is_ok());
-            } else if #[cfg(target_pointer_width = "32")] {
-                // on 32-bit archs the capacity will still be stored on the heap, since the capacity
-                // hasn't changed
-                assert!(box_string.cap.as_usize().is_err());
-            } else {
-                compile_error!("Unsupported target_pointer_width");
-            }
-        }
-
-        // assert the string is still correct
-        assert_eq!(&format!("{}!hello!", string), box_string.as_str());
-    }
-
-    #[test]
-    fn test_realloc_inline_cap_to_inline_cap() {
-        let mut box_string = BoxString::from("hello");
-        // relloc to value < capacity::MAX_VALUE
-        let result = box_string.realloc(128);
-
-        assert_eq!(result.unwrap(), 128);
-        assert_eq!(box_string.as_str(), "hello");
-    }
-
-    #[test]
-    fn test_realloc_inline_cap_to_heap_cap() {
-        let mut box_string = BoxString::from("hello");
-        // relloc to a value > capacity::MAX_VALUE
-        let result = box_string.realloc(SIXTEEN_MB + 128);
-
-        cfg_if::cfg_if! {
-            if #[cfg(target_pointer_width = "64")] {
-                // realloc should succeed since on 64-bit platforms
-                assert_eq!(result.unwrap(), SIXTEEN_MB + 128);
-            } else if #[cfg(target_pointer_width = "32")] {
-                // realloc should fail since we need to go from inline capacity -> heap
-                assert!(result.is_err());
-            } else {
-                compile_error!("Unsupported target_pointer_width");
-            }
-        }
-
-        assert_eq!(box_string.as_str(), "hello");
-    }
-
-    #[test]
-    fn test_realloc_heap_cap_to_heap_cap() {
-        let mut box_string = BoxString::with_capacity(SIXTEEN_MB + 128);
-        box_string.push_str("hello");
-        assert_eq!(box_string.as_str(), "hello");
-        assert_eq!(box_string.capacity(), SIXTEEN_MB + 128);
-
-        // relloc to a value > capacity::MAX_VALUE
-        let result = box_string.realloc(SIXTEEN_MB + 256);
-
-        assert_eq!(result.unwrap(), SIXTEEN_MB + 256);
-        assert_eq!(box_string.as_str(), "hello");
-    }
-
-    #[test]
-    fn test_realloc_heap_cap_to_inline_cap() {
-        let mut box_string = BoxString::with_capacity(SIXTEEN_MB + 128);
-        box_string.push_str("hello");
-        assert_eq!(box_string.as_str(), "hello");
-        assert_eq!(box_string.capacity(), SIXTEEN_MB + 128);
-
-        // relloc to a value < capacity::MAX_VALUE
-        let result = box_string.realloc(128);
-
-        cfg_if::cfg_if! {
-            if #[cfg(target_pointer_width = "64")] {
-                // realloc should succeed since on 64-bit platforms
-                assert_eq!(result.unwrap(), 128);
-            } else if #[cfg(target_pointer_width = "32")] {
-                // realloc should fail since we need to go from inline capacity -> heap
-                assert!(result.is_err());
-            } else {
-                compile_error!("Unsupported target_pointer_width");
-            }
-        }
-
-        assert_eq!(box_string.as_str(), "hello");
-    }
-
-    #[proptest]
-    #[cfg_attr(miri, ignore)]
-    fn proptest_strings_roundtrip(#[strategy(rand_unicode())] word: String) {
-        let box_str = BoxString::from(word.as_str());
-        prop_assert_eq!(&word, box_str.as_str());
-    }
-
-    #[proptest]
-    #[cfg_attr(miri, ignore)]
-    fn proptest_from_string(#[strategy(rand_unicode())] word: String) {
-        let s: String = word.clone();
-        let box_str = BoxString::from_string(s);
-
-        prop_assert_eq!(&word, box_str.as_str());
-    }
-}
-
-crate::asserts::assert_size_eq!(BoxString, String);
diff --git a/compact_str/src/repr/bytes.rs b/compact_str/src/repr/bytes.rs
index 11327b04..0bab577f 100644
--- a/compact_str/src/repr/bytes.rs
+++ b/compact_str/src/repr/bytes.rs
@@ -30,6 +30,9 @@ impl Repr {
     }
 
     /// Collects the bytes from a [`Buf`] into a [`Repr`]
+    ///
+    /// # Safety
+    /// * The caller must guarantee that `buf` is valid UTF-8
     unsafe fn collect_buf<B: Buf>(buf: &mut B) -> (Self, usize) {
         // Get an empty Repr we can write into
         let mut repr = super::EMPTY;
@@ -59,7 +62,7 @@ impl Repr {
 
             // SAFETY: The caller is responsible for making sure the provided buffer is UTF-8. This
             // invariant is documented in the public API
-            let slice = repr.as_mut_slice();
+            let slice = repr.as_mut_buf();
             // write the chunk into the Repr
             slice[bytes_written..bytes_written + chunk_len].copy_from_slice(chunk);
 
@@ -80,42 +83,32 @@ impl Repr {
 mod test {
     use std::io::Cursor;
 
+    use test_case::test_case;
+
     use super::Repr;
 
-    #[test]
-    fn test_smoke() {
-        let word = "hello world";
+    #[test_case(""; "empty")]
+    #[test_case("hello world"; "short")]
+    #[test_case("hello, this is a long string which should be heap allocated"; "long")]
+    fn test_from_utf8_buf(word: &'static str) {
         let mut buf = Cursor::new(word.as_bytes());
-
         let repr = Repr::from_utf8_buf(&mut buf).unwrap();
-        assert_eq!(repr.as_str(), word);
-    }
-
-    #[test]
-    fn test_heap_allocated() {
-        let word = "hello, this is a long string which should be heap allocated";
-        let mut buf = Cursor::new(word.as_bytes());
 
-        let repr = Repr::from_utf8_buf(&mut buf).unwrap();
         assert_eq!(repr.as_str(), word);
+        assert_eq!(repr.len(), word.len());
     }
 
     #[test]
-    fn test_empty() {
-        let mut buf: Cursor<&[u8]> = Cursor::new(&[]);
-
-        let repr = Repr::from_utf8_buf(&mut buf).unwrap();
-        assert_eq!(repr.len(), 0);
-        assert_eq!(repr.as_str(), "");
-    }
-
-    #[test]
-    fn test_packed() {
-        #[cfg(target_pointer_width = "64")]
-        let packed = "this string is 24 chars!";
-        #[cfg(target_pointer_width = "32")]
-        let packed = "i am 12 char";
-
+    fn test_from_utf8_packed() {
+        cfg_if::cfg_if! {
+            if #[cfg(target_pointer_width = "64")] {
+                let packed = "this string is 24 chars!";
+            } else if #[cfg(target_pointer_width = "32")] {
+                let packed = "i am 12 char";
+            } else {
+                compile_error!("unsupported architecture!")
+            }
+        }
         let mut buf = Cursor::new(packed.as_bytes());
 
         let repr = Repr::from_utf8_buf(&mut buf).unwrap();
diff --git a/compact_str/src/repr/capacity.rs b/compact_str/src/repr/capacity.rs
new file mode 100644
index 00000000..2bff6ebb
--- /dev/null
+++ b/compact_str/src/repr/capacity.rs
@@ -0,0 +1,164 @@
+use crate::repr::HEAP_MASK;
+
+// how many bytes a `usize` occupies
+const USIZE_SIZE: usize = core::mem::size_of::<usize>();
+
+/// Used to generate [`CAPACITY_IS_ON_THE_HEAP`]
+#[allow(non_snake_case)]
+const fn CAP_ON_HEAP_FLAG() -> [u8; USIZE_SIZE] {
+    // all bytes 255, with the last being HEAP_MASK
+    let mut flag = [255; USIZE_SIZE];
+    flag[USIZE_SIZE - 1] = HEAP_MASK;
+    flag
+}
+
+/// State that describes the capacity as being stored on the heap.
+///
+/// All bytes `255`, with the last being [`HEAP_MASK`], using the same amount of bytes as `usize`
+/// Example (64-bit): `[255, 255, 255, 255, 255, 255, 255, 254]`
+const CAPACITY_IS_ON_THE_HEAP: [u8; USIZE_SIZE] = CAP_ON_HEAP_FLAG();
+
+// how many bytes we can use for capacity
+const SPACE_FOR_CAPACITY: usize = USIZE_SIZE - 1;
+// the maximum value we're able to store, e.g. on 64-bit arch this is 2^56 - 2
+//
+// note: Preferably we'd used usize.pow(..) here, but that's not a `const fn`, so we need to use
+// bitshift operators, and there's a lint against using them in this pattern, which IMO isn't a
+// great lint
+pub const MAX_VALUE: usize = 2usize.pow(SPACE_FOR_CAPACITY as u32 * 8) - 2;
+
+/// An integer type that uses `core::mem::size_of::<usize>() - 1` bytes to store the capacity of
+/// a heap buffer.
+///
+/// Assumming a 64-bit arch, a [`super::BoxString`] uses 8 bytes for a pointer, 8 bytes for a
+/// length, and then needs 1 byte for a discriminant. We need to store the capacity somewhere, and
+/// we could store it on the heap, but we also have 7 unused bytes. [`Capacity`] handles storing a
+/// value in these 7 bytes, returning an error if it's not possible, at which point we'll store the
+/// capacity on the heap.
+///
+/// # Max Values
+/// * __64-bit:__ `(2 ^ (7 * 8)) - 2 = 72_057_594_037_927_934 ~= 64 petabytes`
+/// * __32-bit:__ `(2 ^ (3 * 8)) - 2 = 16_777_214             ~= 16 megabytes`
+///
+/// Practically speaking, on a 64-bit architecture we'll never need to store the capacity on the
+/// heap, because with it's impossible to create a string that is 64 petabytes or larger. But for
+/// 32-bit architectures we need to be able to store a capacity larger than 16 megabytes, since a
+/// string larger than 16 megabytes probably isn't that uncommon.
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+#[cfg_attr(target_pointer_width = "64", repr(align(8)))]
+#[cfg_attr(target_pointer_width = "32", repr(align(4)))]
+pub struct Capacity([u8; USIZE_SIZE]);
+
+static_assertions::assert_eq_size!(Capacity, usize);
+static_assertions::assert_eq_align!(Capacity, usize);
+
+impl Capacity {
+    #[inline]
+    pub const fn new(capacity: usize) -> Self {
+        cfg_if::cfg_if! {
+            if #[cfg(target_pointer_width = "64")] {
+                // on 64-bit arches we can always fit the capacity inline
+                debug_assert!(capacity <= MAX_VALUE);
+
+                let mut bytes = capacity.to_le_bytes();
+                bytes[core::mem::size_of::<usize>() - 1] = HEAP_MASK;
+                Capacity(bytes)
+            } else if #[cfg(target_pointer_width = "32")] {
+                // on 32-bit arches we might need to store the capacity on the heap
+                if capacity > MAX_VALUE {
+                    // if we need the last byte to encode this capacity then we need to put the capacity on
+                    // the heap. return an Error so `BoxString` can do the right thing
+                    Capacity(CAPACITY_IS_ON_THE_HEAP)
+                } else {
+                    // otherwise, we can store this capacity inline! Set the last byte to be our `HEAP_MASK`
+                    // for our discriminant, using the leading bytes to store the actual value
+                    let mut bytes = capacity.to_le_bytes();
+                    bytes[core::mem::size_of::<usize>() - 1] = HEAP_MASK;
+                    Capacity(bytes)
+                }
+            } else {
+                compile_error!("Unsupported target_pointer_width");
+            }
+        }
+    }
+
+    /// Re-interprets a [`Capacity`] as a `usize`
+    ///
+    /// # SAFETY:
+    /// * `self` must be less than or equal to [`MAX_VALUE`]
+    #[inline(always)]
+    pub unsafe fn as_usize(&self) -> usize {
+        let mut usize_buf = [0u8; USIZE_SIZE];
+        // SAFETY:
+        // * `src` is valid for reads of `SPACE_FOR_CAPACITY` because it is less than `USIZE_SIZE`
+        // * `dst` is valid for reads of `SPACE_FOR_CAPACITY` because it is less than `USIZE_SIZE`
+        // * `src` and `dst` do not overlap because we created `usize_buf`
+        core::ptr::copy_nonoverlapping(self.0.as_ptr(), usize_buf.as_mut_ptr(), SPACE_FOR_CAPACITY);
+        usize::from_le_bytes(usize_buf)
+    }
+
+    /// Returns whether or not this [`Capacity`] has a value that indicates the capacity is being
+    /// stored on the heap
+    #[inline(always)]
+    pub fn is_heap(&self) -> bool {
+        self.0 == CAPACITY_IS_ON_THE_HEAP
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use rayon::prelude::*;
+
+    use super::Capacity;
+
+    #[test]
+    fn test_zero_roundtrips() {
+        let og = 0;
+        let cap = Capacity::new(og);
+        let after = unsafe { cap.as_usize() };
+
+        assert_eq!(og, after);
+    }
+
+    #[test]
+    fn test_max_value() {
+        let available_bytes = (core::mem::size_of::<usize>() - 1) as u32;
+        let max_value = 2usize.pow(available_bytes * 8) - 2;
+
+        #[cfg(target_pointer_width = "64")]
+        assert_eq!(max_value, 72057594037927934);
+        #[cfg(target_pointer_width = "32")]
+        assert_eq!(max_value, 16777214);
+
+        let cap = Capacity::new(max_value);
+        let after = unsafe { cap.as_usize() };
+
+        assert_eq!(max_value, after);
+    }
+
+    #[cfg(target_pointer_width = "32")]
+    #[test]
+
+    fn test_invalid_value() {
+        let invalid_val = usize::MAX;
+        let cap = Capacity::new(invalid_val);
+        let after = unsafe { cap.as_usize() };
+
+        // anything greater than or equal to 16777215, should "resolve" to 16777215
+        assert_eq!(16777215, after);
+    }
+
+    #[test]
+    #[cfg_attr(miri, ignore)]
+    fn test_all_valid_32bit_values() {
+        #[cfg(target_pointer_width = "32")]
+        assert_eq!(16_777_214, super::MAX_VALUE);
+
+        (0..=16_777_214).into_par_iter().for_each(|i| {
+            let cap = Capacity::new(i);
+            let val = unsafe { cap.as_usize() };
+
+            assert_eq!(val, i, "value roundtriped to wrong value?");
+        });
+    }
+}
diff --git a/compact_str/src/repr/discriminant.rs b/compact_str/src/repr/discriminant.rs
deleted file mode 100644
index b4fd8f86..00000000
--- a/compact_str/src/repr/discriminant.rs
+++ /dev/null
@@ -1,32 +0,0 @@
-use super::{
-    HEAP_MASK,
-    PADDING_SIZE,
-};
-
-#[derive(Debug, Copy, Clone)]
-pub enum Discriminant {
-    Heap,
-    Inline,
-}
-
-#[repr(C)]
-#[derive(Debug, Copy, Clone)]
-pub struct DiscriminantMask {
-    _padding: [u8; PADDING_SIZE],
-    val: u8,
-}
-
-impl DiscriminantMask {
-    #[inline(always)]
-    pub const fn discriminant(&self) -> Discriminant {
-        if self.val == u8::MAX {
-            panic!("Discriminant was invalid value reserved for Option::None!")
-        } else if self.val == HEAP_MASK {
-            Discriminant::Heap
-        } else {
-            Discriminant::Inline
-        }
-    }
-}
-
-crate::asserts::assert_size_eq!(DiscriminantMask, String);
diff --git a/compact_str/src/repr/heap.rs b/compact_str/src/repr/heap.rs
index 76e34df5..31054dc9 100644
--- a/compact_str/src/repr/heap.rs
+++ b/compact_str/src/repr/heap.rs
@@ -1,67 +1,549 @@
-use super::boxed::BoxString;
+use core::{
+    cmp,
+    mem,
+    ptr,
+};
+
+use super::capacity::Capacity;
+use super::{
+    Repr,
+    MAX_SIZE,
+};
+
+/// The minimum size we'll allocate on the heap is one usize larger than our max inline size
+const MIN_HEAP_SIZE: usize = MAX_SIZE + mem::size_of::<usize>();
+
+const UNKNOWN: usize = 0;
+pub type StrBuffer = [u8; UNKNOWN];
+
+/// [`HeapBuffer`] grows at an amortized rates of 1.5x
+///
+/// Note: this is different than [`std::string::String`], which grows at a rate of 2x. It's debated
+/// which is better, for now we'll stick with a rate of 1.5x
+#[inline(always)]
+pub fn amortized_growth(cur_len: usize, additional: usize) -> usize {
+    let required = cur_len.saturating_add(additional);
+    let amortized = cur_len.saturating_mul(3) / 2;
+    amortized.max(required)
+}
 
 #[repr(C)]
-#[derive(Debug, Clone)]
-pub struct HeapString {
-    pub string: BoxString,
+pub struct HeapBuffer {
+    pub ptr: ptr::NonNull<u8>,
+    pub len: usize,
+    pub cap: Capacity,
 }
+static_assertions::assert_eq_size!(HeapBuffer, Repr);
 
-impl HeapString {
-    /// Creates a [`HeapString`] from the provided `text`.
-    ///
-    /// If you need to allocate a [`HeapString`] with additional capacity, see
-    /// `HeapString::with_additional()`
+impl HeapBuffer {
+    /// Create a [`HeapBuffer`] with the provided text
     #[inline]
     pub fn new(text: &str) -> Self {
-        let string = BoxString::new(text);
-        HeapString { string }
+        let len = text.len();
+        let (cap, ptr) = allocate_ptr(len);
+
+        // copy our string into the buffer we just allocated
+        //
+        // SAFETY: We know both `src` and `dest` are valid for respectively reads and writes of
+        // length `len` because `len` comes from `src`, and `dest` was allocated to be at least that
+        // length. We also know they're non-overlapping because `dest` is newly allocated
+        unsafe { ptr.as_ptr().copy_from_nonoverlapping(text.as_ptr(), len) };
+
+        HeapBuffer { ptr, len, cap }
+    }
+
+    /// Create an empty [`HeapBuffer`] with a specific capacity
+    #[inline]
+    pub fn with_capacity(capacity: usize) -> Self {
+        let len = 0;
+        let (cap, ptr) = allocate_ptr(capacity);
+
+        HeapBuffer { ptr, len, cap }
     }
 
-    /// Creates a [`HeapString`] from the provided `text` and allocates the underlying buffer with
-    /// `additional` capacity
+    /// Create a [`HeapBuffer`] with `text` that has _at least_ `additional` bytes of capacity
+    ///
+    /// To prevent frequent re-allocations, this method will create a [`HeapBuffer`] with a capacity
+    /// of `text.len() + additional` or `text.len() * 1.5`, whichever is greater
     #[inline]
     pub fn with_additional(text: &str, additional: usize) -> Self {
-        let string = BoxString::with_additional(text, additional);
-        HeapString { string }
+        let len = text.len();
+        let new_capacity = amortized_growth(len, additional);
+        let (cap, ptr) = allocate_ptr(new_capacity);
+
+        // copy our string into the buffer we just allocated
+        //
+        // SAFETY: We know both `src` and `dest` are valid for respectively reads and writes of
+        // length `len` because `len` comes from `src`, and `dest` was allocated to be at least that
+        // length. We also know they're non-overlapping because `dest` is newly allocated
+        unsafe { ptr.as_ptr().copy_from_nonoverlapping(text.as_ptr(), len) };
+
+        HeapBuffer { ptr, len, cap }
     }
 
-    /// Creates a [`HeapString`] with the provided capacity.
+    /// Return the capacity of the [`HeapBuffer`]
     #[inline]
-    pub fn with_capacity(capacity: usize) -> Self {
-        let string = BoxString::with_capacity(capacity);
-        HeapString { string }
+    pub fn capacity(&self) -> usize {
+        #[cold]
+        fn read_capacity_from_heap(this: &HeapBuffer) -> usize {
+            // re-adjust the pointer to include the capacity that's on the heap
+            let adj_ptr: *const u8 = this.ptr.as_ptr().wrapping_sub(mem::size_of::<usize>());
+            let mut buf = [0u8; mem::size_of::<usize>()];
+            // SAFETY: `src` and `dst` don't overlap, and are valid for usize number of bytes
+            unsafe {
+                ptr::copy_nonoverlapping(adj_ptr, buf.as_mut_ptr(), mem::size_of::<usize>());
+            }
+            usize::from_ne_bytes(buf)
+        }
+
+        if self.cap.is_heap() {
+            read_capacity_from_heap(self)
+        } else {
+            // SAFETY: Checked above that the capacity is on the stack
+            unsafe { self.cap.as_usize() }
+        }
+    }
+
+    /// Try to grow the [`HeapBuffer`] by reallocating, returning an error if we fail
+    pub fn realloc(&mut self, new_capacity: usize) -> Result<usize, ()> {
+        let new_cap = Capacity::new(new_capacity);
+
+        // We can't reallocate to a size less than our length, or else we'd clip the string
+        if new_capacity < self.len {
+            return Err(());
+        }
+
+        // HeapBuffer doesn't support 0 byte heap sizes
+        if new_capacity == 0 {
+            return Err(());
+        }
+
+        // Always allocate at least MIN_HEAP_SIZE
+        let new_capacity = cmp::max(new_capacity, MIN_HEAP_SIZE);
+
+        let (new_cap, new_ptr) = match (self.cap.is_heap(), new_cap.is_heap()) {
+            // both current and new capacity can be stored inline
+            (false, false) => {
+                // SAFETY: checked above that our capacity is valid
+                let cap = unsafe { self.cap.as_usize() };
+
+                // current capacity is the same as the new, nothing to do!
+                if cap == new_capacity {
+                    return Ok(new_capacity);
+                }
+
+                let cur_layout = inline_capacity::layout(cap);
+                let new_layout = inline_capacity::layout(new_capacity);
+                let new_size = new_layout.size();
+
+                // It's possible `new_size` could overflow since inline_capacity::layout pads for
+                // alignment
+                if new_size < new_capacity {
+                    return Err(());
+                }
+
+                // SAFETY:
+                // * We're using the same allocator that we used for `ptr`
+                // * The layout is the same because we checked that the capacity is inline
+                // * `new_size` will be > 0, we return early if the requested capacity is 0
+                // * Checked above if `new_size` overflowed when rounding to alignment
+                match ptr::NonNull::new(unsafe {
+                    std::alloc::realloc(self.ptr.as_ptr(), cur_layout, new_size)
+                }) {
+                    Some(ptr) => (new_cap, ptr),
+                    None => return Err(()),
+                }
+            }
+            // both current and new capacity need to be stored on the heap
+            (true, true) => {
+                let cur_layout = heap_capacity::layout(self.capacity());
+                let new_layout = heap_capacity::layout(new_capacity);
+                let new_size = new_layout.size();
+
+                // alloc::realloc requires that size > 0
+                debug_assert!(new_size > 0);
+
+                // It's possible `new_size` could overflow since heap_capacity::layout requires a
+                // few additional bytes
+                if new_size < new_capacity {
+                    return Err(());
+                }
+
+                // move our pointer back one WORD since our capacity is behind it
+                let raw_ptr = self.ptr.as_ptr();
+                let adj_ptr = raw_ptr.wrapping_sub(mem::size_of::<usize>());
+
+                // SAFETY:
+                // * We're using the same allocator that we used for `ptr`
+                // * The layout is the same because we checked that the capacity is on the heap
+                // * `new_size` will be > 0, we return early if the requested capacity is 0
+                // * Checked above if `new_size` overflowed when rounding to alignment
+                let cap_ptr = unsafe { std::alloc::realloc(adj_ptr, cur_layout, new_size) };
+                // Check if reallocation succeeded
+                if cap_ptr.is_null() {
+                    return Err(());
+                }
+
+                // Our allocation succeeded! Write the new capacity
+                //
+                // SAFTEY:
+                // * `src` and `dst` are both valid for reads of `usize` number of bytes
+                // * `src` and `dst` don't overlap because we created `src`
+                unsafe {
+                    ptr::copy_nonoverlapping(
+                        new_capacity.to_ne_bytes().as_ptr(),
+                        cap_ptr,
+                        mem::size_of::<usize>(),
+                    )
+                };
+
+                // Finally, adjust our pointer backup so it points at the string content
+                let str_ptr = cap_ptr.wrapping_add(mem::size_of::<usize>());
+                // SAFETY: We checked above to make sure the pointer was non-null
+                let ptr = unsafe { ptr::NonNull::new_unchecked(str_ptr) };
+
+                (new_cap, ptr)
+            }
+            // capacity is currently inline or on the heap, but needs to move, can't realloc because
+            // we'd need to change the layout!
+            (false, true) | (true, false) => return Err(()),
+        };
+
+        // set our new pointer and new capacity
+        self.ptr = new_ptr;
+        self.cap = new_cap;
+
+        Ok(new_capacity)
     }
 
+    /// Set's the length of the content for this [`HeapBuffer`]
+    ///
+    /// # SAFETY:
+    /// * The caller must guarantee that `len` bytes in the buffer are valid UTF-8
     #[inline]
-    pub fn from_string(s: String) -> Self {
-        let string = BoxString::from_string(s);
-        HeapString { string }
+    pub unsafe fn set_len(&mut self, len: usize) {
+        self.len = len;
     }
 
+    /// Deallocates the memory owned by the provided [`HeapBuffer`]
     #[inline]
-    pub fn into_string(self) -> String {
-        self.string.into_string()
+    pub fn dealloc(&mut self) {
+        deallocate_ptr(self.ptr, self.cap);
+    }
+}
+
+impl Clone for HeapBuffer {
+    fn clone(&self) -> Self {
+        // Create a new HeapBuffer with the same capacity as the original
+        let mut new = Self::with_capacity(self.capacity());
+
+        // SAFETY:
+        // * `src` and `dst` don't overlap because we just created `dst`
+        // * `src` and `dst` are both valid for `self.len` bytes because self.len < capacity
+        unsafe {
+            new.ptr
+                .as_ptr()
+                .copy_from_nonoverlapping(self.ptr.as_ptr(), self.len)
+        };
+        // SAFETY:
+        // * We copied the text from self, which is valid UTF-8
+        unsafe { new.set_len(self.len) };
+
+        new
+    }
+}
+
+impl Drop for HeapBuffer {
+    fn drop(&mut self) {
+        self.dealloc()
+    }
+}
+
+/// Allocates a buffer on the heap that we can use to store a string, optionally stores the capacity
+/// of said buffer on the heap.
+///
+/// Returns a [`Capacity`] that either indicates the capacity is stored on the heap, or is stored
+/// in the `Capacity` itself.
+#[inline]
+pub fn allocate_ptr(capacity: usize) -> (Capacity, ptr::NonNull<u8>) {
+    // We allocate at least MIN_HEAP_SIZE bytes because we need to allocate at least one byte
+    let capacity = capacity.max(MIN_HEAP_SIZE);
+    let cap = Capacity::new(capacity);
+
+    // HeapBuffer doesn't support 0 sized allocations, we should always allocate at least
+    // MIN_HEAP_SIZE bytes
+    debug_assert!(capacity > 0);
+
+    #[cold]
+    fn allocate_with_capacity_on_heap(capacity: usize) -> ptr::NonNull<u8> {
+        // write our capacity onto the heap
+        let ptr = heap_capacity::alloc(capacity);
+        // SAFETY:
+        // * `src` and `dst` don't overlap and are both valid for `usize` bytes
+        unsafe {
+            ptr::copy_nonoverlapping(
+                capacity.to_ne_bytes().as_ptr(),
+                ptr.as_ptr(),
+                mem::size_of::<usize>(),
+            )
+        };
+        let raw_ptr = ptr.as_ptr().wrapping_add(core::mem::size_of::<usize>());
+        // SAFETY: We know `raw_ptr` is non-null because we just created it
+        unsafe { ptr::NonNull::new_unchecked(raw_ptr) }
+    }
+
+    let ptr = if cap.is_heap() {
+        allocate_with_capacity_on_heap(capacity)
+    } else {
+        unsafe { inline_capacity::alloc(capacity) }
+    };
+
+    (cap, ptr)
+}
+
+/// Deallocates a buffer on the heap, handling when the capacity is also stored on the heap
+#[inline]
+pub fn deallocate_ptr(ptr: ptr::NonNull<u8>, cap: Capacity) {
+    #[cold]
+    fn deallocate_with_capacity_on_heap(ptr: ptr::NonNull<u8>) {
+        // re-adjust the pointer to include the capacity that's on the heap
+        let adj_ptr = ptr.as_ptr().wrapping_sub(mem::size_of::<usize>());
+        // read the capacity from the heap so we know how much to deallocate
+        let mut buf = [0u8; mem::size_of::<usize>()];
+        // SAFETY: `src` and `dst` don't overlap, and are valid for usize number of bytes
+        unsafe {
+            ptr::copy_nonoverlapping(adj_ptr, buf.as_mut_ptr(), mem::size_of::<usize>());
+        }
+        let capacity = usize::from_ne_bytes(buf);
+        // SAFETY: We know the pointer is not null since we got it as a NonNull
+        let ptr = unsafe { ptr::NonNull::new_unchecked(adj_ptr) };
+        // SAFETY: We checked above that our capacity is on the heap, and we readjusted the
+        // pointer to reference the capacity
+        unsafe { heap_capacity::dealloc(ptr, capacity) }
     }
 
+    if cap.is_heap() {
+        deallocate_with_capacity_on_heap(ptr);
+    } else {
+        // SAFETY: Our capacity is always inline on 64-bit archs
+        unsafe { inline_capacity::dealloc(ptr, cap.as_usize()) }
+    }
+}
+
+mod heap_capacity {
+    use core::ptr;
+    use std::alloc;
+
+    use super::StrBuffer;
+
     #[inline]
-    pub fn from_box_str(b: Box<str>) -> Self {
-        let string = BoxString::from_box_str(b);
-        HeapString { string }
+    pub fn alloc(capacity: usize) -> ptr::NonNull<u8> {
+        let layout = layout(capacity);
+        debug_assert!(layout.size() > 0);
+
+        // SAFETY: `alloc(...)` has undefined behavior if the layout is zero-sized. We know the
+        // layout can't be zero-sized though because we're always at least allocating one `usize`
+        let raw_ptr = unsafe { alloc::alloc(layout) };
+
+        // Check to make sure our pointer is non-null, some allocators return null pointers instead
+        // of panicking
+        match ptr::NonNull::new(raw_ptr) {
+            Some(ptr) => ptr,
+            None => alloc::handle_alloc_error(layout),
+        }
     }
 
-    /// Makes a mutable reference to the underlying buffer.
+    /// Deallocates a pointer which references a `HeapBuffer` whose capacity is on the heap
     ///
-    /// # Invariants
-    /// * Please see `super::Repr` for all invariants
-    #[inline]
-    pub unsafe fn make_mut_slice(&mut self) -> &mut [u8] {
-        self.string.as_mut_slice()
+    /// # Saftey
+    /// * `ptr` must point to the start of a `HeapBuffer` whose capacity is on the heap. i.e. we
+    ///   must have `ptr -> [cap<usize> ; string<bytes>]`
+    pub unsafe fn dealloc(ptr: ptr::NonNull<u8>, capacity: usize) {
+        let layout = layout(capacity);
+        alloc::dealloc(ptr.as_ptr(), layout);
+    }
+
+    #[repr(C)]
+    struct HeapBufferInnerHeapCapacity {
+        capacity: usize,
+        buffer: StrBuffer,
+    }
+
+    #[inline(always)]
+    pub fn layout(capacity: usize) -> alloc::Layout {
+        let buffer_layout = alloc::Layout::array::<u8>(capacity).expect("valid capacity");
+        alloc::Layout::new::<HeapBufferInnerHeapCapacity>()
+            .extend(buffer_layout)
+            .expect("valid layout")
+            .0
+            .pad_to_align()
     }
+}
 
+mod inline_capacity {
+    use core::ptr;
+    use std::alloc;
+
+    use super::StrBuffer;
+
+    /// # SAFETY:
+    /// * `capacity` must be > 0
     #[inline]
-    pub unsafe fn set_len(&mut self, length: usize) {
-        self.string.set_len(length)
+    pub unsafe fn alloc(capacity: usize) -> ptr::NonNull<u8> {
+        let layout = layout(capacity);
+        debug_assert!(layout.size() > 0);
+
+        // SAFETY: `alloc(...)` has undefined behavior if the layout is zero-sized. We specify that
+        // `capacity` must be > 0 as a constraint to uphold the safety of this method. If capacity
+        // is greater than 0, then our layout will be non-zero-sized.
+        let raw_ptr = alloc::alloc(layout);
+
+        // Check to make sure our pointer is non-null, some allocators return null pointers instead
+        // of panicking
+        match ptr::NonNull::new(raw_ptr) {
+            Some(ptr) => ptr,
+            None => alloc::handle_alloc_error(layout),
+        }
+    }
+
+    /// Deallocates a pointer which references a `HeapBuffer` whose capacity is stored inline
+    ///
+    /// # Saftey
+    /// * `ptr` must point to the start of a `HeapBuffer` whose capacity is on the inline
+    pub unsafe fn dealloc(ptr: ptr::NonNull<u8>, capacity: usize) {
+        let layout = layout(capacity);
+        alloc::dealloc(ptr.as_ptr(), layout);
+    }
+
+    #[repr(C)]
+    struct HeapBufferInnerInlineCapacity {
+        buffer: StrBuffer,
+    }
+
+    #[inline(always)]
+    pub fn layout(capacity: usize) -> alloc::Layout {
+        let buffer_layout = alloc::Layout::array::<u8>(capacity).expect("valid capacity");
+        alloc::Layout::new::<HeapBufferInnerInlineCapacity>()
+            .extend(buffer_layout)
+            .expect("valid layout")
+            .0
+            .pad_to_align()
     }
 }
 
-crate::asserts::assert_size_eq!(HeapString, String);
+#[cfg(test)]
+mod test {
+    use test_case::test_case;
+
+    use super::{
+        HeapBuffer,
+        MIN_HEAP_SIZE,
+    };
+
+    const EIGHTEEN_MB: usize = 18 * 1024 * 1024;
+
+    #[test]
+    fn test_min_capacity() {
+        let h = HeapBuffer::new("short");
+        assert_eq!(h.capacity(), MIN_HEAP_SIZE);
+    }
+
+    #[test_case(&[42; 8]; "short")]
+    #[test_case(&[42; 50]; "long")]
+    #[test_case(&[42; EIGHTEEN_MB]; "huge")]
+    fn test_capacity(buf: &[u8]) {
+        // we know the buffer is valid UTF-8
+        let s = unsafe { core::str::from_utf8_unchecked(buf) };
+        let h = HeapBuffer::new(s);
+
+        assert_eq!(h.capacity(), core::cmp::max(s.len(), MIN_HEAP_SIZE));
+    }
+
+    #[test_case(&[42; 0], 0, Err(MIN_HEAP_SIZE); "empty_empty")]
+    #[test_case(&[42; 64], 0, Err(64); "short_empty")]
+    #[test_case(&[42; 64], 32, Err(64); "short_to_shorter")]
+    #[test_case(&[42; 64], 128, Ok(128); "short_to_longer")]
+    #[test_case(&[42; EIGHTEEN_MB], EIGHTEEN_MB + 128, Ok(EIGHTEEN_MB + 128); "heap_to_heap")]
+    fn test_realloc(buf: &[u8], realloc: usize, result: Result<usize, usize>) {
+        // we know the buffer is valid UTF-8
+        let s = unsafe { core::str::from_utf8_unchecked(buf) };
+        let mut h = HeapBuffer::new(s);
+
+        // reallocate, asserting our result
+        let expected_cap = match result {
+            Ok(c) | Err(c) => c,
+        };
+        let expected_res = result.map_err(|_| ());
+        assert_eq!(h.realloc(realloc), expected_res);
+        assert_eq!(h.capacity(), expected_cap);
+    }
+
+    #[test]
+    fn test_realloc_inline_to_heap() {
+        // we know the buffer is valid UTF-8
+        let s = unsafe { core::str::from_utf8_unchecked(&[42; 128]) };
+        let mut h = HeapBuffer::new(s);
+
+        cfg_if::cfg_if! {
+            if #[cfg(target_pointer_width = "64")] {
+                let expected_result = Ok(EIGHTEEN_MB);
+                let expected_capacity = EIGHTEEN_MB;
+            } else if #[cfg(target_pointer_width = "32")] {
+                // on 32-bit architectures we'd need to change the layout from capacity being inline
+                // to the capacity being on the heap, which isn't possible
+                let expected_result = Err(());
+                let expected_capacity = 128;
+            } else {
+                compile_error!("Unsupported pointer width!");
+            }
+        }
+        assert_eq!(h.realloc(EIGHTEEN_MB), expected_result);
+        assert_eq!(h.capacity(), expected_capacity);
+    }
+
+    #[test_case(&[42; 64], 128, 100, Ok(100); "sanity")]
+    fn test_realloc_shrink(
+        buf: &[u8],
+        realloc_one: usize,
+        realloc_two: usize,
+        exp_result: Result<usize, usize>,
+    ) {
+        // we know the buffer is valid UTF-8
+        let s = unsafe { core::str::from_utf8_unchecked(buf) };
+        let mut h = HeapBuffer::new(s);
+
+        assert!(
+            realloc_one > realloc_two,
+            "we have to grow before we can shrink"
+        );
+
+        // grow our allocation
+        assert_eq!(h.realloc(realloc_one), Ok(realloc_one));
+
+        // shrink our allocation, asserting our result
+        let expected_cap = match exp_result {
+            Ok(c) | Err(c) => c,
+        };
+        let expected_res = exp_result.map_err(|_| ());
+        assert_eq!(h.realloc(realloc_two), expected_res);
+        assert_eq!(h.capacity(), expected_cap);
+    }
+
+    #[test]
+    fn test_realloc_shrink_heap_to_inline() {
+        // TODO: test this case
+        assert!(true)
+    }
+
+    #[test_case(&[42; 0]; "empty")]
+    #[test_case(&[42; 3]; "short")]
+    #[test_case(&[42; 64]; "long")]
+    #[test_case(&[42; EIGHTEEN_MB]; "huge")]
+    fn test_clone(buf: &[u8]) {
+        let s = unsafe { core::str::from_utf8_unchecked(buf) };
+        let h_a = HeapBuffer::new(s);
+        let h_b = h_a.clone();
+
+        assert_eq!(h_a.capacity(), h_b.capacity());
+    }
+}
diff --git a/compact_str/src/repr/inline.rs b/compact_str/src/repr/inline.rs
index 758d114f..e0f15359 100644
--- a/compact_str/src/repr/inline.rs
+++ b/compact_str/src/repr/inline.rs
@@ -1,32 +1,45 @@
-use super::MAX_SIZE;
+use core::ptr;
 
-const LENGTH_MASK: u8 = 0b11000000;
+use super::{
+    Repr,
+    LENGTH_MASK,
+    MAX_SIZE,
+};
 
-#[repr(C)]
-#[derive(Debug, Copy, Clone)]
-pub struct InlineString {
-    buffer: [u8; MAX_SIZE],
-}
+/// A buffer stored on the stack whose size is equal to the stack size of `String`
+#[repr(transparent)]
+pub struct InlineBuffer(pub [u8; MAX_SIZE]);
+static_assertions::assert_eq_size!(InlineBuffer, Repr);
 
-impl InlineString {
+impl InlineBuffer {
+    /// Construct a new [`InlineString`]. A string that lives in a small buffer on the stack
+    ///
+    /// SAFETY:
+    /// * The caller must guarantee that the length of `text` is less than [`MAX_SIZE`]
     #[inline]
-    pub fn new(text: &str) -> Self {
+    pub unsafe fn new(text: &str) -> Self {
         debug_assert!(text.len() <= MAX_SIZE);
 
         let len = text.len();
         let mut buffer = [0u8; MAX_SIZE];
 
-        // set the length
+        // set the length in the last byte
         buffer[MAX_SIZE - 1] = len as u8 | LENGTH_MASK;
 
-        // copy the string
+        // copy the string into our buffer
         //
         // note: in the case where len == MAX_SIZE, we'll overwrite the len, but that's okay because
         // when reading the length we can detect that the last byte is part of UTF-8 and return a
         // length of MAX_SIZE
-        unsafe { std::ptr::copy_nonoverlapping(text.as_ptr(), buffer.as_mut_ptr(), len) };
+        //
+        // SAFETY:
+        // * src (`text`) is valid for `len` bytes because `len` comes from `text`
+        // * dst (`buffer`) is valid for `len` bytes because we assert src is less than MAX_SIZE
+        // * src and dst don't overlap because we created dst
+        //
+        ptr::copy_nonoverlapping(text.as_ptr(), buffer.as_mut_ptr(), len);
 
-        InlineString { buffer }
+        InlineBuffer(buffer)
     }
 
     #[inline]
@@ -51,100 +64,40 @@ impl InlineString {
             i -= 1;
         }
 
-        InlineString { buffer }
-    }
-
-    /// Creates an [`InlineString`] from raw parts without checking that it's valid UTF-8
-    #[inline]
-    pub const unsafe fn from_parts(len: usize, mut buffer: [u8; MAX_SIZE]) -> Self {
-        if len != MAX_SIZE {
-            buffer[MAX_SIZE - 1] = len as u8 | LENGTH_MASK;
-        }
-        InlineString { buffer }
+        InlineBuffer(buffer)
     }
 
+    /// Returns an empty [`InlineBuffer`]
     #[inline(always)]
-    pub fn len(&self) -> usize {
-        let last_byte = self.buffer[MAX_SIZE - 1];
-        core::cmp::min((last_byte.wrapping_sub(LENGTH_MASK)) as usize, MAX_SIZE)
+    pub const fn empty() -> Self {
+        Self::new_const("")
     }
 
-    #[inline]
-    pub const fn capacity(&self) -> usize {
-        MAX_SIZE
-    }
-
-    #[inline]
-    pub fn as_str(&self) -> &str {
-        // SAFETY: You can only safely construct an InlineString via a &str which also properly sets
-        // the length of the string
-        unsafe {
-            let slice = self.as_slice().get_unchecked(..self.len());
-            ::std::str::from_utf8_unchecked(slice)
-        }
-    }
-
-    #[inline]
-    pub fn as_slice(&self) -> &[u8] {
-        self.buffer.as_slice()
-    }
-
-    /// Provides a mutable reference to the underlying buffer
+    /// Set's the length of the content for this [`InlineBuffer`]
     ///
-    /// # Safety
-    /// * Please see `super::Repr` for all invariants
+    /// # SAFETY:
+    /// * The caller must guarantee that `len` bytes in the buffer are valid UTF-8
     #[inline]
-    pub unsafe fn as_mut_slice(&mut self) -> &mut [u8] {
-        self.buffer.as_mut_slice()
-    }
-
-    #[inline]
-    pub unsafe fn set_len(&mut self, length: usize) {
-        debug_assert!(length <= MAX_SIZE);
+    pub unsafe fn set_len(&mut self, len: usize) {
+        debug_assert!(len <= MAX_SIZE);
 
         // If `length` == MAX_SIZE, then we infer the length to be the capacity of the buffer. We
         // can infer this because the way we encode length doesn't overlap with any valid UTF-8
         // bytes
-        if length < MAX_SIZE {
-            self.buffer[MAX_SIZE - 1] = length as u8 | LENGTH_MASK;
+        if len < MAX_SIZE {
+            self.0[MAX_SIZE - 1] = len as u8 | LENGTH_MASK;
         }
     }
-}
 
-crate::asserts::assert_size_eq!(InlineString, String);
+    #[inline(always)]
+    pub fn copy(&self) -> Self {
+        InlineBuffer(self.0)
+    }
+}
 
 #[cfg(test)]
 mod tests {
-    use std::convert::TryFrom;
-
-    use proptest::prelude::*;
     use rayon::prelude::*;
-    use test_strategy::proptest;
-
-    use super::{
-        InlineString,
-        MAX_SIZE,
-    };
-    use crate::tests::rand_unicode_with_max_len;
-
-    #[test]
-    fn test_sanity() {
-        let hello = "hello world!";
-        let inline = InlineString::new(hello);
-
-        assert_eq!(inline.as_str(), hello);
-        assert_eq!(inline.len(), hello.len());
-        assert_eq!(inline.capacity(), MAX_SIZE);
-    }
-
-    #[proptest]
-    #[cfg_attr(miri, ignore)]
-    fn proptest_roundtrip(#[strategy(rand_unicode_with_max_len(MAX_SIZE))] s: String) {
-        let inline = InlineString::new(&s);
-
-        prop_assert_eq!(inline.len(), s.len());
-        prop_assert_eq!(inline.as_str(), s);
-    }
 
     #[test]
     #[ignore] // we run this in CI, but unless you're compiling in release, this takes a while
diff --git a/compact_str/src/repr/iter.rs b/compact_str/src/repr/iter.rs
index d601d334..18bb7771 100644
--- a/compact_str/src/repr/iter.rs
+++ b/compact_str/src/repr/iter.rs
@@ -1,11 +1,10 @@
-//! Implementations of the [`FromIterator`] trait to make building `CompactString`s more ergonomic
+//! Implementations of the [`FromIterator`] trait to make building [`Repr`]s more ergonomic
 
 use core::iter::FromIterator;
 use std::borrow::Cow;
 
 use super::{
-    HeapString,
-    InlineString,
+    InlineBuffer,
     Repr,
     MAX_SIZE,
 };
@@ -18,13 +17,12 @@ impl FromIterator<char> for Repr {
         // If the size hint indicates we can't store this inline, then create a heap string
         let (size_hint, _) = iter.size_hint();
         if size_hint > MAX_SIZE {
-            let heap = HeapString::from_string(iter.collect());
-            return Repr::from_heap(heap);
+            return Repr::from_string(iter.collect());
         }
 
         // Otherwise, continuously pull chars from the iterator
         let mut curr_len = 0;
-        let mut inline_buf = [0u8; MAX_SIZE];
+        let mut inline_buf = InlineBuffer::new_const("");
         while let Some(c) = iter.next() {
             let char_len = c.len_utf8();
 
@@ -32,29 +30,27 @@ impl FromIterator<char> for Repr {
             // string
             if char_len + curr_len > MAX_SIZE {
                 let (min_remaining, _) = iter.size_hint();
-                let mut heap_buf = String::with_capacity(char_len + curr_len + min_remaining);
+                let mut string = String::with_capacity(char_len + curr_len + min_remaining);
 
                 // push existing characters onto the heap
                 // SAFETY: `inline_buf` has been filled with `char`s which are valid UTF-8
-                heap_buf
-                    .push_str(unsafe { core::str::from_utf8_unchecked(&inline_buf[..curr_len]) });
+                string
+                    .push_str(unsafe { core::str::from_utf8_unchecked(&inline_buf.0[..curr_len]) });
                 // push current char onto the heap
-                heap_buf.push(c);
+                string.push(c);
                 // extend heap with remaining characters
-                heap_buf.extend(iter);
+                string.extend(iter);
 
-                let heap = HeapString::from_string(heap_buf);
-                return Repr::from_heap(heap);
+                return Repr::from_string(string);
             }
 
             // write the current char into a slice of the unoccupied space
-            c.encode_utf8(&mut inline_buf[curr_len..]);
+            c.encode_utf8(&mut inline_buf.0[curr_len..]);
             curr_len += char_len;
         }
 
-        // SAFETY: We know `inline_buf` is valid UTF-8 because it consists entriely of `char`s
-        let inline = unsafe { InlineString::from_parts(curr_len, inline_buf) };
-        Repr::from_inline(inline)
+        unsafe { inline_buf.set_len(curr_len) }
+        unsafe { core::mem::transmute(inline_buf) }
     }
 }
 
@@ -77,7 +73,7 @@ where
 
     // Continuously pull strings from the iterator
     let mut curr_len = 0;
-    let mut inline_buf = [0u8; MAX_SIZE];
+    let mut inline_buf = InlineBuffer::new_const("");
     while let Some(s) = iter.next() {
         let str_slice = s.as_ref();
         let bytes_len = str_slice.len();
@@ -85,28 +81,26 @@ where
         // this new string is too large to fit into our inline buffer, so heap allocate the rest
         if bytes_len + curr_len > MAX_SIZE {
             let (min_remaining, _) = iter.size_hint();
-            let mut heap_buf = String::with_capacity(bytes_len + curr_len + min_remaining);
+            let mut string = String::with_capacity(bytes_len + curr_len + min_remaining);
 
             // push existing strings onto the heap
             // SAFETY: `inline_buf` has been filled with `&str`s which are valid UTF-8
-            heap_buf.push_str(unsafe { core::str::from_utf8_unchecked(&inline_buf[..curr_len]) });
+            string.push_str(unsafe { core::str::from_utf8_unchecked(&inline_buf.0[..curr_len]) });
             // push current string onto the heap
-            heap_buf.push_str(str_slice);
+            string.push_str(str_slice);
             // extend heap with remaining strings
-            heap_buf.extend(iter);
+            string.extend(iter);
 
-            let heap = HeapString::from_string(heap_buf);
-            return Repr::from_heap(heap);
+            return Repr::from_string(string);
         }
 
         // write the current string into a slice of the unoccupied space
-        inline_buf[curr_len..][..bytes_len].copy_from_slice(str_slice.as_bytes());
+        inline_buf.0[curr_len..][..bytes_len].copy_from_slice(str_slice.as_bytes());
         curr_len += bytes_len;
     }
 
-    // SAFETY: We know `inline_buf` is valid UTF-8 because it consists entriely of `&str`s
-    let inline = unsafe { InlineString::from_parts(curr_len, inline_buf) };
-    Repr::from_inline(inline)
+    unsafe { inline_buf.set_len(curr_len) }
+    unsafe { core::mem::transmute(inline_buf) }
 }
 
 impl<'a> FromIterator<&'a str> for Repr {
diff --git a/compact_str/src/repr/mod.rs b/compact_str/src/repr/mod.rs
index f0716529..8e168c5a 100644
--- a/compact_str/src/repr/mod.rs
+++ b/compact_str/src/repr/mod.rs
@@ -1,14 +1,14 @@
+use core::str::Utf8Error;
+use core::{
+    mem,
+    ptr,
+};
 use std::borrow::Cow;
-use std::fmt;
-use std::iter::Extend;
-use std::mem::ManuallyDrop;
-use std::str::Utf8Error;
 
 #[cfg(feature = "bytes")]
 mod bytes;
 
-mod boxed;
-mod discriminant;
+mod capacity;
 mod heap;
 mod inline;
 mod iter;
@@ -16,30 +16,22 @@ mod nonmax;
 mod num;
 mod traits;
 
-use discriminant::{
-    Discriminant,
-    DiscriminantMask,
-};
-use heap::HeapString;
-use inline::InlineString;
+use capacity::Capacity;
+use heap::HeapBuffer;
+use inline::InlineBuffer;
 use nonmax::NonMaxU8;
 pub use traits::IntoRepr;
 
+/// The max size of a string we can fit inline
 pub const MAX_SIZE: usize = std::mem::size_of::<String>();
-
-const PADDING_SIZE: usize = MAX_SIZE - std::mem::size_of::<u8>();
-const EMPTY: Repr = Repr::from_inline(InlineString::new_const(""));
-
 /// Used as a discriminant to identify different variants
 pub const HEAP_MASK: u8 = 0b11111110;
+/// When our string is stored inline, we represent the length of the string in the last byte, offset
+/// by `LENGTH_MASK`
+pub const LENGTH_MASK: u8 = 0b11000000;
+
+const EMPTY: Repr = Repr::new_inline("");
 
-/// This is the "compiler facing" representation for the struct that underpins `CompactString`. The
-/// odd layout enables the compiler to represent an `Option<CompactString>` in the same amount of
-/// bytes as `CompactString`. In other words, it allows the compiler to see a "niche" value in
-/// `Repr`, which it then uses to store the `None` variant, without requiring any extra bytes.
-///
-/// We want the size of `size_of::<Repr>()` (and thus `CompactString`) to be the same as
-/// `size_of::<String>()`, so we construct a `Repr` with the following fields.
 #[repr(C)]
 pub struct Repr(
     // We have a pointer in the repesentation to properly carry provenance
@@ -54,30 +46,25 @@ pub struct Repr(
     NonMaxU8,
 );
 
-#[repr(C)]
-union ReprUnion {
-    mask: DiscriminantMask,
-    heap: ManuallyDrop<HeapString>,
-    inline: InlineString,
-}
-
 unsafe impl Send for Repr {}
 unsafe impl Sync for Repr {}
 
 impl Repr {
     #[inline]
-    pub fn new<T: AsRef<str>>(text: T) -> Self {
-        let text = text.as_ref();
+    pub fn new(text: &str) -> Self {
         let len = text.len();
 
         if len == 0 {
             EMPTY
         } else if len <= MAX_SIZE {
-            let inline = InlineString::new(text);
-            Repr::from_inline(inline)
+            // SAFETY: We checked that the length of text is less than or equal to MAX_SIZE
+            let inline = unsafe { InlineBuffer::new(text) };
+            // SAFETY: `InlineString` and `Repr` are the same size
+            unsafe { mem::transmute(inline) }
         } else {
-            let heap = HeapString::new(text);
-            Repr::from_heap(heap)
+            let heap = HeapBuffer::new(text);
+            // SAFETY: `BoxString` and `Repr` are the same size
+            unsafe { mem::transmute(heap) }
         }
     }
 
@@ -86,23 +73,26 @@ impl Repr {
         let len = text.len();
 
         if len <= MAX_SIZE {
-            let inline = InlineString::new_const(text);
-            Repr::from_inline(inline)
+            let inline = InlineBuffer::new_const(text);
+            // SAFETY: `InlineString` and `Repr` are the same size
+            unsafe { mem::transmute(inline) }
         } else {
             panic!("Inline string was too long, max length is `std::mem::size_of::<CompactString>()` bytes");
         }
     }
 
+    /// Create a [`Repr`] with the provided `capacity`
     #[inline]
     pub fn with_capacity(capacity: usize) -> Self {
         if capacity <= MAX_SIZE {
             EMPTY
         } else {
-            let heap = HeapString::with_capacity(capacity);
-            Repr::from_heap(heap)
+            let heap = HeapBuffer::with_capacity(capacity);
+            unsafe { mem::transmute(heap) }
         }
     }
 
+    /// Create a [`Repr`] from a slice of bytes that is UTF-8
     #[inline]
     pub fn from_utf8<B: AsRef<[u8]>>(buf: B) -> Result<Self, Utf8Error> {
         // Get a &str from the Vec, failing if it's not valid UTF-8
@@ -111,6 +101,11 @@ impl Repr {
         Ok(Self::new(s))
     }
 
+    /// Create a [`Repr`] from a slice of bytes that is UTF-8, without validating that it is indeed
+    /// UTF-8
+    ///
+    /// # Safety
+    /// * The caller must guarantee that `buf` is valid UTF-8
     #[inline]
     pub unsafe fn from_utf8_unchecked<B: AsRef<[u8]>>(buf: B) -> Self {
         let bytes = buf.as_ref();
@@ -134,7 +129,7 @@ impl Repr {
 
         // SAFETY: The caller is responsible for making sure the provided buffer is UTF-8. This
         // invariant is documented in the public API
-        let slice = repr.as_mut_slice();
+        let slice = repr.as_mut_buf();
         // write the chunk into the Repr
         slice[..bytes_len].copy_from_slice(bytes);
 
@@ -145,93 +140,233 @@ impl Repr {
         repr
     }
 
+    /// Create a [`Repr`] from a [`String`], in `O(1)` time.
+    ///
+    /// Note: If the provided [`String`] is >16 MB and we're on a 32-bit arch, we'll copy the
+    /// `String`.
     #[inline]
     pub fn from_string(s: String) -> Self {
-        if s.capacity() == 0 {
+        let og_cap = s.capacity();
+        let cap = Capacity::new(og_cap);
+
+        #[cold]
+        fn capacity_on_heap(s: String) -> Repr {
+            let heap = HeapBuffer::new(s.as_str());
+            // SAFETY: `HeapBuffer` and `Repr` are the same size
+            unsafe { mem::transmute(heap) }
+        }
+
+        #[cold]
+        fn empty() -> Repr {
             EMPTY
+        }
+
+        if cap.is_heap() {
+            // We only hit this case if the provided String is > 16MB and we're on a 32-bit arch. We
+            // expect it to be unlikely, thus we hint that to the compiler
+            capacity_on_heap(s)
+        } else if og_cap == 0 {
+            // We don't expect converting from an empty String often, so we make this code path cold
+            empty()
         } else {
-            let heap = HeapString::from_string(s);
-            Repr::from_heap(heap)
+            let mut s = mem::ManuallyDrop::new(s.into_bytes());
+            let len = s.len();
+            let raw_ptr = s.as_mut_ptr();
+
+            let ptr = ptr::NonNull::new(raw_ptr).expect("string with capacity has null ptr?");
+            let heap = HeapBuffer { ptr, len, cap };
+
+            // SAFETY: `HeapBuffer` and `Repr` are the same size
+            unsafe { mem::transmute(heap) }
         }
     }
 
+    /// Converts a [`Repr`] into a [`String`], in `O(1)` time, if possible
     #[inline]
     pub fn into_string(self) -> String {
-        if self.capacity() == 0 {
-            String::new()
-        } else {
-            match self.cast_into_owned() {
-                StrongOwnedRepr::Inline(inline) => String::from(inline.as_str()),
-                StrongOwnedRepr::Heap(heap) => {
-                    // `HeapString::into_string()` takes ownership and
-                    // is responsible for avoiding a double-free.
-                    ManuallyDrop::into_inner(heap).into_string()
-                }
-            }
+        let last_byte = self.last_byte();
+
+        #[cold]
+        fn into_string_heap(this: HeapBuffer) -> String {
+            // SAFETY: We know pointer is valid for `length` bytes
+            let slice = unsafe { core::slice::from_raw_parts(this.ptr.as_ptr(), this.len) };
+            // SAFETY: A `Repr` contains valid UTF-8
+            let s = unsafe { core::str::from_utf8_unchecked(slice) };
+
+            String::from(s)
         }
-    }
 
-    #[inline]
-    pub fn from_box_str(b: Box<str>) -> Self {
-        if b.len() == 0 {
-            EMPTY
+        if last_byte == HEAP_MASK {
+            // SAFTEY: this is only ever called if we're heap allocated
+            let heap_buffer: HeapBuffer = unsafe { mem::transmute(self) };
+
+            if heap_buffer.cap.is_heap() {
+                // We don't expect capacity to be on the heap often, so we mark it as cold
+                into_string_heap(heap_buffer)
+            } else {
+                // Wrap the BoxString in a ManuallyDrop so the underlying buffer doesn't get freed
+                let this = mem::ManuallyDrop::new(heap_buffer);
+
+                // SAFETY: We checked above to make sure capacity is valid
+                let cap = unsafe { this.cap.as_usize() };
+
+                // SAFETY:
+                // * The memory in `ptr` was previously allocated by the same allocator the standard
+                //   library uses, with a required alignment of exactly 1.
+                // * `length` is less than or equal to capacity, due to internal invaraints.
+                // * `capacity` is correctly maintained internally.
+                // * `BoxString` only ever contains valid UTF-8.
+                unsafe { String::from_raw_parts(this.ptr.as_ptr(), this.len, cap) }
+            }
         } else {
-            let heap = HeapString::from_box_str(b);
-            Repr::from_heap(heap)
+            let pointer = &self as *const _ as *const u8;
+            let length = core::cmp::min((last_byte.wrapping_sub(LENGTH_MASK)) as usize, MAX_SIZE);
+
+            // SAFETY: We know pointer is valid for `length` bytes
+            let slice = unsafe { core::slice::from_raw_parts(pointer, length) };
+            // SAFETY: A `Repr` contains valid UTF-8
+            let s = unsafe { core::str::from_utf8_unchecked(slice) };
+
+            String::from(s)
         }
     }
 
     #[inline]
-    pub fn len(&self) -> usize {
-        self.cast().len()
-    }
+    pub fn from_box_str(s: Box<str>) -> Self {
+        let og_cap = s.len();
+        let cap = Capacity::new(og_cap);
+
+        #[cold]
+        fn capacity_on_heap(s: Box<str>) -> Repr {
+            let heap = HeapBuffer::new(&s);
+            // SAFETY: `BoxString` and `Repr` are the same size
+            unsafe { mem::transmute(heap) }
+        }
 
-    #[inline]
-    pub fn capacity(&self) -> usize {
-        self.cast().capacity()
+        #[cold]
+        fn empty() -> Repr {
+            EMPTY
+        }
+
+        if cap.is_heap() {
+            // We only hit this case if the provided String is > 16MB and we're on a 32-bit arch. We
+            // expect it to be unlikely, thus we hint that to the compiler
+            capacity_on_heap(s)
+        } else if og_cap == 0 {
+            // We don't expect converting from an empty String often, so we make this code path cold
+            empty()
+        } else {
+            // Don't drop the box here
+            let raw_ptr = Box::into_raw(s).cast::<u8>();
+            let ptr = ptr::NonNull::new(raw_ptr).expect("string with capacity has null ptr?");
+
+            // create a new BoxString with our parts!
+            let heap = HeapBuffer {
+                ptr,
+                len: og_cap,
+                cap,
+            };
+
+            // SAFETY: `BoxString` and `Repr` are the same size
+            unsafe { mem::transmute(heap) }
+        }
     }
 
+    /// Reserves at least `additional` bytes. If there is already enough capacity to store
+    /// `additional` bytes this is a no-op
     #[inline]
     pub fn reserve(&mut self, additional: usize) {
-        // We want at least enough capacity to store length + additional
-        let new_capacity = self
-            .len()
+        let len = self.len();
+        let needed_capacity = len
             .checked_add(additional)
-            .expect("resulting capacity does not fit into usize");
+            .expect("Attempted to reserve more than 'usize' bytes");
 
-        // We already have at least `additional` capacity, so we don't need to do anything
-        if self.capacity() >= new_capacity {
+        if needed_capacity < self.capacity() {
+            // we already have enough space, no-op
             return;
         }
 
-        if new_capacity <= MAX_SIZE {
-            // It's possible to have a `CompactString` that is heap allocated with a capacity less
-            // than MAX_SIZE, if that `CompactString` was created From a String or
-            // Box<str>.
-            let inline = InlineString::new(self.as_str());
-            *self = Repr::from_inline(inline)
+        if needed_capacity <= MAX_SIZE {
+            // It's possible to have a `Repr` that is heap allocated with a capacity less than
+            // MAX_SIZE, if that `Repr` was created From a String or Box<str>
+            //
+            // SAFTEY: Our needed_capacity is >= our length, which is <= than MAX_SIZE
+            let inline = unsafe { InlineBuffer::new(self.as_str()) };
+            // SAFETY: `InlineBuffer` and `Repr` are the same size
+            *self = unsafe { mem::transmute(inline) };
+        } else if !self.is_heap_allocated() {
+            // We're not heap allocated, but need to be, create a HeapBuffer
+            let heap = HeapBuffer::with_additional(self.as_str(), additional);
+            // SAFETY: `HeapBuffer` and `Repr` are the same size
+            *self = unsafe { mem::transmute(heap) };
         } else {
-            // Create a `HeapString` with `text.len() + additional` capacity
-            let heap = HeapString::with_additional(self.as_str(), additional);
-
-            // Replace `self` with the new Repr
-            *self = Repr::from_heap(heap);
+            // We're already heap allocated, but we need more capacity
+            let heap_buffer = unsafe { &mut *(self as *mut _ as *mut HeapBuffer) };
+
+            // To reduce allocations, we amortize our growth
+            let amortized_capacity = heap::amortized_growth(len, additional);
+            // Attempt to grow our capacity, allocating a new HeapBuffer on failure
+            if heap_buffer.realloc(amortized_capacity).is_err() {
+                // Create a new HeapBuffer
+                let heap = HeapBuffer::with_additional(self.as_str(), additional);
+                // SAFETY: `HeapBuffer` and `Repr` are the same size
+                *self = unsafe { mem::transmute(heap) };
+            }
         }
     }
 
-    #[inline]
-    pub fn as_str(&self) -> &str {
-        self.cast().into_str()
+    pub fn shrink_to(&mut self, min_capacity: usize) {
+        let last_byte = self.last_byte();
+
+        // Note: We can't shrink the inline variant since it's buffer is a fixed size, so we only
+        // take action here if our string is heap allocated
+        if last_byte == HEAP_MASK {
+            let heap = unsafe { &mut *(self as *mut _ as *mut HeapBuffer) };
+
+            let old_capacity = heap.capacity();
+            let new_capacity = heap.len.max(min_capacity);
+
+            if new_capacity <= MAX_SIZE {
+                // // String can be inlined.
+                let mut inline = InlineBuffer::empty();
+                unsafe {
+                    inline
+                        .0
+                        .as_mut_ptr()
+                        .copy_from_nonoverlapping(heap.ptr.as_ptr(), heap.len)
+                };
+                unsafe { inline.set_len(heap.len) }
+                *self = unsafe { mem::transmute(inline) };
+            } else if new_capacity < old_capacity {
+                // String can be shrunk.
+                // We can ignore the result. The string keeps its old capacity, but that's okay.
+                let _ = heap.realloc(new_capacity);
+            }
+        }
     }
 
     #[inline]
-    pub fn as_slice(&self) -> &[u8] {
-        self.cast().into_slice()
-    }
+    pub fn push_str(&mut self, s: &str) {
+        let len = self.len();
+        let str_len = s.len();
 
-    #[inline]
-    pub unsafe fn as_mut_slice(&mut self) -> &mut [u8] {
-        self.cast_mut().into_mut_slice()
+        // Reserve at least enough space to fit `s`
+        self.reserve(str_len);
+
+        // SAFTEY: `s` which we're appending to the buffer, is valid UTF-8
+        let slice = unsafe { self.as_mut_buf() };
+        let push_buffer = &mut slice[len..len + str_len];
+
+        debug_assert_eq!(push_buffer.len(), s.as_bytes().len());
+
+        // Copy the string into our buffer
+        push_buffer.copy_from_slice(s.as_bytes());
+
+        // Increment the length of our string
+        //
+        // SAFETY: We appened `s` which is valid UTF-8, and if our size became greater than
+        // MAX_SIZE, our call to reserve would make us heap allocated
+        unsafe { self.set_len(len + str_len) };
     }
 
     #[inline]
@@ -244,137 +379,171 @@ impl Repr {
         Some(ch)
     }
 
+    /// Returns the string content, and only the string content, as a slice of bytes.
     #[inline]
-    pub fn push_str(&mut self, s: &str) {
-        let len = self.len();
-        let str_len = s.len();
-
-        // Reserve at least enough space for our str, possibly causing a heap allocation
-        self.reserve(str_len);
-
-        let slice = unsafe { self.as_mut_slice() };
-        let buffer = &mut slice[len..len + str_len];
-
-        debug_assert_eq!(buffer.len(), s.as_bytes().len());
+    pub fn as_slice(&self) -> &[u8] {
+        // the last byte stores our discriminant and stack length
+        let last_byte = self.last_byte();
+
+        // initially has the value of the stack pointer, conditionally becomes the heap pointer
+        let mut pointer = self as *const Self as *const u8;
+        let heap_pointer = self.0 as *const u8;
+
+        let pointer_ref = &mut pointer;
+
+        // initially has the value of the stack length, conditionally becomes the heap length
+        let mut length = core::cmp::min((last_byte.wrapping_sub(LENGTH_MASK)) as usize, MAX_SIZE);
+        let heap_length = self.1;
+        let length_ref = &mut length;
+
+        // our discriminant is stored in the last byte and denotes stack vs heap
+        //
+        // Note: We should never add an `else` statement here, keeping the conditional simple allows
+        // the compiler to optimize this to a conditional-move instead of a branch
+        if last_byte == HEAP_MASK {
+            *pointer_ref = heap_pointer;
+            *length_ref = heap_length;
+        }
 
-        // Copy the string into our buffer
-        buffer.copy_from_slice(s.as_bytes());
-        // Incrament the length of our string
-        unsafe { self.set_len(len + str_len) };
+        unsafe { core::slice::from_raw_parts(pointer, length) }
     }
 
     #[inline]
-    pub unsafe fn set_len(&mut self, length: usize) {
-        self.cast_mut().set_len(length)
+    pub fn as_str(&self) -> &str {
+        // SAFETY: A `Repr` contains valid UTF-8
+        unsafe { core::str::from_utf8_unchecked(self.as_slice()) }
     }
 
+    /// Returns the length of the string that we're storing
+    #[allow(clippy::len_without_is_empty)] // is_empty exists on CompactString
     #[inline]
-    pub fn is_heap_allocated(&self) -> bool {
-        matches!(self.discriminant(), Discriminant::Heap)
-    }
+    pub fn len(&self) -> usize {
+        // the last byte stores our discriminant and stack length
+        let last_byte = self.last_byte();
+
+        // initially has the value of the stack length, conditionally becomes the heap length
+        let mut length = core::cmp::min((last_byte.wrapping_sub(LENGTH_MASK)) as usize, MAX_SIZE);
+        let heap_length = self.1;
+        let length_ref = &mut length;
+
+        // our discriminant is stored in the last byte and denotes stack vs heap
+        //
+        // Note: We should never add an `else` statement here, keeping the conditional simple allows
+        // the compiler to optimize this to a conditional-move instead of a branch
+        if last_byte == HEAP_MASK {
+            *length_ref = heap_length;
+        }
 
-    #[inline(always)]
-    fn discriminant(&self) -> Discriminant {
-        // SAFETY: `heap` and `inline` all store a discriminant in their last byte
-        unsafe { self.as_union().mask.discriminant() }
+        *length_ref
     }
 
-    #[inline(always)]
-    fn cast(&self) -> StrongRepr<'_> {
-        match self.discriminant() {
-            Discriminant::Heap => {
-                // SAFETY: We checked the discriminant to make sure the union is `heap`
-                StrongRepr::Heap(unsafe { &self.as_union().heap })
-            }
-            Discriminant::Inline => {
-                // SAFETY: We checked the discriminant to make sure the union is `inline`
-                StrongRepr::Inline(unsafe { &self.as_union().inline })
-            }
+    /// Returns the overall capacity of the underlying buffer
+    #[inline]
+    pub fn capacity(&self) -> usize {
+        // the last byte stores our discriminant and stack length
+        let last_byte = self.last_byte();
+
+        #[cold]
+        fn heap_capacity(this: &Repr) -> usize {
+            // SAFETY: A `HeapBuffer` and `Repr` have the same size
+            let heap_buffer = unsafe { &*(this as *const _ as *const HeapBuffer) };
+            heap_buffer.capacity()
         }
-    }
 
-    #[inline(always)]
-    fn cast_mut(&mut self) -> MutStrongRepr<'_> {
-        match self.discriminant() {
-            Discriminant::Heap => {
-                // SAFETY: We checked the discriminant to make sure the union is `heap`
-                MutStrongRepr::Heap(unsafe { &mut self.as_union_mut().heap })
-            }
-            Discriminant::Inline => {
-                // SAFETY: We checked the discriminant to make sure the union is `inline`
-                MutStrongRepr::Inline(unsafe { &mut self.as_union_mut().inline })
-            }
+        if last_byte == HEAP_MASK {
+            heap_capacity(self)
+        } else {
+            MAX_SIZE
         }
     }
 
     #[inline(always)]
-    fn cast_into_owned(self) -> StrongOwnedRepr {
-        match self.discriminant() {
-            Discriminant::Heap => {
-                // SAFETY: We checked the discriminant to make sure the union is `heap`
-                StrongOwnedRepr::Heap(unsafe { self.into_union().heap })
-            }
-            Discriminant::Inline => {
-                // SAFETY: We checked the discriminant to make sure the union is `inline`
-                StrongOwnedRepr::Inline(unsafe { self.into_union().inline })
-            }
-        }
+    pub fn is_heap_allocated(&self) -> bool {
+        let last_byte = self.last_byte();
+        last_byte == HEAP_MASK
     }
 
-    #[inline(always)]
-    const fn from_inline(repr: InlineString) -> Self {
-        // SAFETY: An `InlineString` and `Repr` have the same size
-        unsafe { std::mem::transmute(repr) }
-    }
+    /// Return a mutable reference to the entirely underlying buffer
+    ///
+    /// # Safety
+    /// * Callers must guarantee that any modifications made to the buffer are valid UTF-8
+    pub unsafe fn as_mut_buf(&mut self) -> &mut [u8] {
+        // the last byte stores our discriminant and stack length
+        let last_byte = self.last_byte();
 
-    #[inline(always)]
-    const fn from_heap(repr: HeapString) -> Self {
-        // SAFETY: An `HeapString` and `Repr` have the same size
-        unsafe { std::mem::transmute(repr) }
-    }
+        let (ptr, cap) = if last_byte == HEAP_MASK {
+            // SAFETY: A `HeapBuffer` and `Repr` have the same size
+            let heap_buffer = &*(self as *const _ as *const HeapBuffer);
+            let ptr = heap_buffer.ptr.as_ptr();
+            let cap = heap_buffer.capacity();
 
-    #[inline(always)]
-    fn as_union(&self) -> &ReprUnion {
-        // SAFETY: An `ReprUnion` and `Repr` have the same size
-        unsafe { &*(self as *const _ as *const _) }
-    }
+            (ptr, cap)
+        } else {
+            let ptr = self as *mut Self as *mut u8;
+            (ptr, MAX_SIZE)
+        };
 
-    #[inline(always)]
-    fn as_union_mut(&mut self) -> &mut ReprUnion {
-        // SAFETY: An `ReprUnion` and `Repr` have the same size
-        unsafe { &mut *(self as *mut _ as *mut _) }
+        // SAFETY: Our data is valid for `cap` bytes, and is initialized
+        core::slice::from_raw_parts_mut(ptr, cap)
     }
 
-    #[inline(always)]
-    fn into_union(self) -> ReprUnion {
-        // SAFETY: An `ReprUnion` and `Repr` have the same size
-        unsafe { std::mem::transmute(self) }
+    /// Sets the length of the string that our underlying buffer contains
+    ///
+    /// # Safety
+    /// * `len` bytes in the buffer must be valid UTF-8
+    /// * If the underlying buffer is stored inline, `len` must be <= MAX_SIZE
+    pub unsafe fn set_len(&mut self, len: usize) {
+        let last_byte = self.last_byte();
+
+        if last_byte == HEAP_MASK {
+            // SAFETY: A `HeapBuffer` and `Repr` have the same size
+            let heap_buffer = &mut *(self as *mut _ as *mut HeapBuffer);
+            heap_buffer.set_len(len);
+        } else {
+            // SAFETY: A `InlineBuffer` and `Repr` have the same size
+            let inline_buffer = &mut *(self as *mut _ as *mut InlineBuffer);
+            // SAFETY: The caller guarantees that len <= MAX_SIZE
+            inline_buffer.set_len(len);
+        }
     }
 
-    pub(crate) fn shrink_to(&mut self, min_capacity: usize) {
-        let heap = match self.cast_mut() {
-            MutStrongRepr::Inline(_) => return,
-            MutStrongRepr::Heap(heap) => heap,
+    /// Returns the last byte that's on the stack.
+    ///
+    /// The last byte stores the discriminant that indicates whether the string is on the stack or
+    /// on the heap. When the string is on the stack the last byte also stores the length
+    #[inline(always)]
+    const fn last_byte(&self) -> u8 {
+        cfg_if::cfg_if! {
+            if #[cfg(target_pointer_width = "64")] {
+                let last_byte = self.5;
+            } else if #[cfg(target_pointer_width = "32")] {
+                let last_byte = self.4;
+            } else {
+                compile_error!("Unsupported target_pointer_width");
+            }
         };
-
-        let old_capacity = heap.string.capacity();
-        let new_capacity = heap.string.len().max(min_capacity);
-        if new_capacity <= MAX_SIZE {
-            // String can be inlined.
-            *self = Repr::from_inline(InlineString::new(heap.string.as_str()));
-        } else if new_capacity < old_capacity {
-            // String can be shrunk.
-            // We can ignore the result. The string keeps its old capacity, but that's okay.
-            let _ = heap.string.realloc(new_capacity);
-        }
+        last_byte as u8
     }
 }
 
 impl Clone for Repr {
+    #[inline]
     fn clone(&self) -> Self {
-        match self.cast() {
-            StrongRepr::Heap(heap) => Repr::from_heap((**heap).clone()),
-            StrongRepr::Inline(inline) => Repr::from_inline(*inline),
+        let last_byte = self.last_byte();
+
+        #[cold]
+        fn clone_heap(this: &Repr) -> Repr {
+            let heap = unsafe { &*(this as *const _ as *const HeapBuffer) };
+            let new = heap.clone();
+            unsafe { mem::transmute(new) }
+        }
+
+        if last_byte == HEAP_MASK {
+            clone_heap(self)
+        } else {
+            let inline = unsafe { &*(self as *const _ as *const InlineBuffer) };
+            let new = inline.copy();
+            unsafe { mem::transmute(new) }
         }
     }
 }
@@ -388,16 +557,11 @@ impl Drop for Repr {
             outlined_drop(self)
         }
 
-        #[inline(never)]
+        #[cold]
         fn outlined_drop(this: &mut Repr) {
-            match this.discriminant() {
-                Discriminant::Heap => {
-                    // SAFETY: We checked the discriminant to make sure the union is `heap`
-                    unsafe { ManuallyDrop::drop(&mut this.as_union_mut().heap) };
-                }
-                // No-op, the value is on the stack and doesn't need to be explicitly dropped
-                Discriminant::Inline => {}
-            }
+            // SAFTEY: this is only ever called if we're heap allocated
+            let heap_buffer: &mut HeapBuffer = unsafe { &mut *(this as *mut _ as *mut _) };
+            heap_buffer.dealloc();
         }
     }
 }
@@ -413,53 +577,8 @@ impl Extend<char> for Repr {
         }
         let (lower_bound, _) = iterator.size_hint();
 
-        match self.cast_mut() {
-            MutStrongRepr::Heap(heap) => heap.string.extend(iterator),
-            MutStrongRepr::Inline(inline) => {
-                // Check if the lower_bound of the iterator indicates we'll need to heap allocate
-                if lower_bound + inline.len() > MAX_SIZE {
-                    let mut heap = HeapString::with_additional(inline.as_str(), lower_bound);
-                    heap.string.extend(iterator);
-
-                    // Replace `self` with the new Repr
-                    *self = Repr::from_heap(heap);
-                    return;
-                }
-
-                // Keep pulling characters off the iterator, eventually heap allocating if we run
-                // out of space inline!
-                while let Some(ch) = iterator.next() {
-                    let inline_len = inline.len();
-                    let char_len = ch.len_utf8();
-
-                    if inline_len + char_len <= MAX_SIZE {
-                        // SAFTEY: We're writing a `char` into the buffer, which we know is valid
-                        // UTF-8
-                        let buffer = unsafe { inline.as_mut_slice() };
-                        // Write the character into our buffer
-                        ch.encode_utf8(&mut buffer[inline_len..]);
-                        // SAFETY: We just wrote `char_len` bytes into the buffer, so we know this
-                        // is a valid length
-                        unsafe { inline.set_len(inline_len + char_len) };
-                    } else {
-                        // We can't fit the remainder of the iterator in an InlineString, so we
-                        // either need to make a HeapString
-                        let mut heap = HeapString::with_additional(inline.as_str(), lower_bound);
-
-                        // push the char we just popped off, but couldn't fit inline
-                        heap.string.push(ch);
-                        // write in the rest of the iterator!
-                        heap.string.extend(iterator);
-
-                        // Replace `self` with the new Repr
-                        *self = Repr::from_heap(heap);
-
-                        // All done!
-                        return;
-                    }
-                }
-            }
-        }
+        self.reserve(lower_bound);
+        iterator.for_each(|c| self.push_str(c.encode_utf8(&mut [0; 4])));
     }
 }
 
@@ -493,367 +612,245 @@ impl Extend<String> for Repr {
     }
 }
 
-impl fmt::Write for Repr {
-    fn write_str(&mut self, s: &str) -> fmt::Result {
-        self.push_str(s);
-        Ok(())
-    }
-
-    fn write_fmt(mut self: &mut Self, args: fmt::Arguments<'_>) -> fmt::Result {
-        match args.as_str() {
-            Some(s) => {
-                self.push_str(s);
-                Ok(())
-            }
-            None => fmt::write(&mut self, args),
-        }
-    }
-}
-
-#[derive(Debug)]
-enum StrongRepr<'a> {
-    Inline(&'a InlineString),
-    Heap(&'a ManuallyDrop<HeapString>),
-}
-
-impl<'a> StrongRepr<'a> {
-    #[inline]
-    pub fn len(self) -> usize {
-        match self {
-            Self::Inline(inline) => inline.len(),
-            Self::Heap(heap) => heap.string.len(),
-        }
-    }
-
-    #[inline]
-    pub fn capacity(self) -> usize {
-        match self {
-            Self::Inline(inline) => inline.capacity(),
-            Self::Heap(heap) => heap.string.capacity(),
-        }
-    }
-
-    #[inline]
-    pub fn into_str(self) -> &'a str {
-        match self {
-            Self::Inline(inline) => inline.as_str(),
-            Self::Heap(heap) => heap.string.as_str(),
-        }
-    }
-
-    #[inline]
-    pub fn into_slice(self) -> &'a [u8] {
-        match self {
-            Self::Inline(inline) => inline.as_slice(),
-            Self::Heap(heap) => heap.string.as_slice(),
-        }
-    }
-}
-
-#[derive(Debug)]
-enum MutStrongRepr<'a> {
-    Inline(&'a mut InlineString),
-    Heap(&'a mut ManuallyDrop<HeapString>),
-}
-
-impl<'a> MutStrongRepr<'a> {
-    #[inline]
-    pub unsafe fn into_mut_slice(self) -> &'a mut [u8] {
-        match self {
-            Self::Inline(inline) => inline.as_mut_slice(),
-            Self::Heap(heap) => heap.make_mut_slice(),
-        }
-    }
-
-    #[inline]
-    pub unsafe fn set_len(self, length: usize) {
-        match self {
-            Self::Inline(inline) => inline.set_len(length),
-            Self::Heap(heap) => heap.set_len(length),
-        }
-    }
-}
-
-#[derive(Debug)]
-enum StrongOwnedRepr {
-    Inline(InlineString),
-    Heap(ManuallyDrop<HeapString>),
-}
-
-crate::asserts::assert_size_eq!(ReprUnion, Repr, Option<Repr>, String, Option<String>);
-
-#[cfg(target_pointer_width = "64")]
-crate::asserts::assert_size!(Repr, 24);
-#[cfg(target_pointer_width = "32")]
-crate::asserts::assert_size!(Repr, 12);
-
 #[cfg(test)]
 mod tests {
+    use quickcheck_macros::quickcheck;
+    use test_case::test_case;
+
     use super::{
         Repr,
-        HEAP_MASK,
         MAX_SIZE,
     };
 
-    #[test]
-    fn test_inline_str() {
-        let short = "abc";
-        let repr = Repr::new(&short);
-        assert_eq!(repr.as_str(), short);
+    const EIGHTEEN_MB: usize = 18 * 1024 * 1024;
+    const EIGHTEEN_MB_STR: &'static str =
+        unsafe { core::str::from_utf8_unchecked(&[42; EIGHTEEN_MB]) };
+
+    #[test_case("hello world!"; "inline")]
+    #[test_case("this is a long string that should be stored on the heap"; "heap")]
+    fn test_create(s: &'static str) {
+        let repr = Repr::new(s);
+        assert_eq!(repr.as_str(), s);
+        assert_eq!(repr.len(), s.len());
+    }
+
+    #[quickcheck]
+    #[cfg_attr(miri, ignore)]
+    fn quickcheck_create(s: String) {
+        let repr = Repr::new(&s);
+        assert_eq!(repr.as_str(), s);
+        assert_eq!(repr.len(), s.len());
+    }
+
+    #[test_case(0; "empty")]
+    #[test_case(10; "short")]
+    #[test_case(64; "long")]
+    #[test_case(EIGHTEEN_MB; "huge")]
+    fn test_with_capacity(cap: usize) {
+        let r = Repr::with_capacity(cap);
+        assert!(r.capacity() >= MAX_SIZE);
+        assert_eq!(r.len(), 0);
+    }
+
+    #[test_case(""; "empty")]
+    #[test_case("abc"; "short")]
+    #[test_case("hello world! I am a longer string 🦀"; "long")]
+    fn test_from_utf8_valid(s: &'static str) {
+        let bytes = s.as_bytes();
+        let r = Repr::from_utf8(bytes).expect("valid UTF-8");
+
+        assert_eq!(r.as_str(), s);
+        assert_eq!(r.len(), s.len());
+    }
+
+    #[quickcheck]
+    #[cfg_attr(miri, ignore)]
+    fn quickcheck_from_utf8(buf: Vec<u8>) {
+        match (core::str::from_utf8(&buf), Repr::from_utf8(&buf)) {
+            (Ok(s), Ok(r)) => {
+                assert_eq!(r.as_str(), s);
+                assert_eq!(r.len(), s.len());
+            }
+            (Err(e), Err(r)) => assert_eq!(e, r),
+            _ => panic!("core::str and Repr differ on what is valid UTF-8!"),
+        }
     }
 
-    #[test]
-    fn test_packed_str() {
-        #[cfg(target_pointer_width = "64")]
-        let packed = "this string is 24 chars!";
-        #[cfg(target_pointer_width = "32")]
-        let packed = "i am 12 char";
-
-        let repr = Repr::new(&packed);
-        assert_eq!(repr.as_str(), packed);
+    #[test_case(String::new(); "empty")]
+    #[test_case(String::from("nyc 🗽"); "short")]
+    #[test_case(String::from("this is a really long string, which is intended"); "long")]
+    fn test_from_string(s: String) {
+        let r = Repr::from_string(s.clone());
+        assert_eq!(r.len(), s.len());
+        assert_eq!(r.as_str(), s.as_str());
     }
 
-    #[test]
-    fn test_heap_str() {
-        let long = "I am a long string that has very many characters";
-        let repr = Repr::new(&long);
-        assert_eq!(repr.as_str(), long);
+    #[quickcheck]
+    #[cfg_attr(miri, ignore)]
+    fn quickcheck_from_string(s: String) {
+        let r = Repr::from_string(s.clone());
+        assert_eq!(r.len(), s.len());
+        assert_eq!(r.as_str(), s.as_str());
     }
 
-    #[test]
-    fn test_reserve() {
-        let word = std::mem::size_of::<usize>();
-
-        let short = "abc";
-        let mut repr = Repr::new(&short);
-
-        assert_eq!(repr.capacity(), word * 3);
-        assert_eq!(repr.as_str(), short);
-
-        // Reserve < WORD * 3
-        repr.reserve(word);
-        // This shouldn't cause a resize
-        assert_eq!(repr.capacity(), word * 3);
-        // We should not be heap allocated
-        assert!(!repr.is_heap_allocated());
-
-        // Reserve a large amount of bytes
-        repr.reserve(128);
+    #[test_case(""; "empty")]
+    #[test_case("nyc 🗽"; "short")]
+    #[test_case("this is a really long string, which is intended"; "long")]
+    fn test_into_string(control: &'static str) {
+        let r = Repr::new(control);
+        let s = r.into_string();
 
-        // We should get resized
-        assert_eq!(repr.capacity(), 128 + short.len());
-        // The string should still be the same
-        assert_eq!(repr.as_str(), short);
-        // We should be heap allocated
-        assert!(repr.is_heap_allocated());
+        assert_eq!(control.len(), s.len());
+        assert_eq!(control, s.as_str());
     }
 
-    #[test]
-    fn test_write_to_buffer() {
-        let mut repr = Repr::new("");
-        let slice = unsafe { repr.as_mut_slice() };
-
-        let word = "abc";
-        let new_len = word.len();
-
-        // write bytes into the `CompactString`
-        slice[..new_len].copy_from_slice(word.as_bytes());
-        // set the length
-        unsafe { repr.set_len(new_len) }
+    #[quickcheck]
+    #[cfg_attr(miri, ignore)]
+    fn quickcheck_into_string(control: String) {
+        let r = Repr::new(&control);
+        let s = r.into_string();
 
-        assert_eq!(repr.as_str(), word);
+        assert_eq!(control.len(), s.len());
+        assert_eq!(control, s.as_str());
     }
 
-    #[test]
-    fn test_write_to_resized_buffer() {
-        let mut repr = Repr::new("");
-
-        // reserve additional bytes
-        repr.reserve(100);
-        assert!(repr.is_heap_allocated());
-
-        let slice = unsafe { repr.as_mut_slice() };
+    #[test_case("", "a", false; "empty")]
+    #[test_case("", "🗽", false; "empty_emoji")]
+    #[test_case("abc", "🗽🙂🦀🌈👏🐶", true; "inline_to_heap")]
+    #[test_case("i am a long string that will be on the heap", "extra", true; "heap_to_heap")]
+    fn test_push_str(control: &'static str, append: &'static str, is_heap: bool) {
+        let mut r = Repr::new(control);
+        let mut c = String::from(control);
 
-        let long_word = "hello, I am a very long string that should be allocated on the heap";
-        let new_len = long_word.len();
+        r.push_str(append);
+        c.push_str(append);
 
-        slice[..new_len].copy_from_slice(long_word.as_bytes());
-        unsafe { repr.set_len(new_len) }
+        assert_eq!(r.as_str(), c.as_str());
+        assert_eq!(r.len(), c.len());
 
-        assert_eq!(repr.as_str(), long_word);
+        assert_eq!(r.is_heap_allocated(), is_heap);
     }
 
-    #[test]
-    fn test_pop() {
-        let example = "hello";
-        let mut repr = Repr::new(example);
+    #[quickcheck]
+    #[cfg_attr(miri, ignore)]
+    fn quickcheck_push_str(control: String, append: String) {
+        let mut r = Repr::new(&control);
+        let mut c = control;
 
-        assert_eq!(repr.pop(), Some('o'));
-        assert_eq!(repr.pop(), Some('l'));
-        assert_eq!(repr.pop(), Some('l'));
+        r.push_str(&append);
+        c.push_str(&append);
 
-        assert_eq!(repr.as_str(), "he");
-        assert_eq!(repr.len(), 2);
+        assert_eq!(r.as_str(), c.as_str());
+        assert_eq!(r.len(), c.len());
     }
 
-    #[test]
-    fn test_push_str() {
-        let example = "hello";
-        let mut repr = Repr::new(example);
+    #[test_case(&[42; 0], &[42; EIGHTEEN_MB]; "empty_to_heap_capacity")]
+    #[test_case(&[42; 8], &[42; EIGHTEEN_MB]; "inline_to_heap_capacity")]
+    #[test_case(&[42; 128], &[42; EIGHTEEN_MB]; "heap_inline_to_heap_capacity")]
+    #[test_case(&[42; EIGHTEEN_MB], &[42; 64]; "heap_capacity_to_heap_capacity")]
+    fn test_push_str_from_buf(buf: &[u8], append: &[u8]) {
+        // The goal of this test is to exercise the scenario when our capacity is stored on the heap
 
-        repr.push_str(" world!");
+        let control = unsafe { core::str::from_utf8_unchecked(buf) };
+        let append = unsafe { core::str::from_utf8_unchecked(append) };
 
-        assert_eq!(repr.as_str(), "hello world!");
-        assert_eq!(repr.len(), 12);
-    }
+        let mut r = Repr::new(control);
+        let mut c = String::from(control);
 
-    #[test]
-    fn test_extend_chars() {
-        let example = "hello";
-        let mut repr = Repr::new(example);
+        r.push_str(append);
+        c.push_str(append);
 
-        repr.extend(" world".chars());
+        assert_eq!(r.as_str(), c.as_str());
+        assert_eq!(r.len(), c.len());
 
-        assert_eq!(repr.len(), 11);
-        assert_eq!(repr.as_str(), "hello world");
-        assert!(!repr.is_heap_allocated());
+        assert!(r.is_heap_allocated());
     }
 
-    #[test]
-    fn test_extend_chars_can_heap_allocate() {
-        let start = "hello";
-        let mut repr = Repr::new(start);
-
-        let chars = (0..100).map(|_| '!');
-        repr.extend(chars);
+    #[test_case("", 0, false; "empty_zero")]
+    #[test_case("", 10, false; "empty_small")]
+    #[test_case("", 64, true; "empty_large")]
+    #[test_case("abc", 0, false; "short_zero")]
+    #[test_case("abc", 8, false; "short_small")]
+    #[test_case("abc", 64, true; "short_large")]
+    #[test_case("I am a long string that will be on the heap", 0, true; "large_zero")]
+    #[test_case("I am a long string that will be on the heap", 10, true; "large_small")]
+    #[test_case("I am a long string that will be on the heap", EIGHTEEN_MB, true; "large_huge")]
+    fn test_reserve(initial: &'static str, additional: usize, is_heap: bool) {
+        let mut r = Repr::new(initial);
+        r.reserve(additional);
 
-        let mut control = String::from(start);
-        let chars2 = (0..100).map(|_| '!');
-        control.extend(chars2);
-
-        assert_eq!(repr.as_str(), control.as_str());
-        assert_eq!(repr.len(), 105);
-    }
-
-    #[test]
-    fn test_extend_chars_can_make_packed_repr() {
-        let start = "nyc";
-        let mut repr = Repr::new(start);
-
-        let num_chars = super::MAX_SIZE - start.len();
-        let chars = (0..num_chars).map(|_| '!');
-
-        repr.extend(chars);
-        assert_eq!(repr.len(), super::MAX_SIZE);
-        assert!(!repr.is_heap_allocated());
+        assert!(r.capacity() >= initial.len() + additional);
+        assert_eq!(r.is_heap_allocated(), is_heap);
     }
 
     #[test]
-    fn test_extend_short_heap_variant() {
-        let start = "this is a long string that will be heap allocated";
-        let mut repr = Repr::new(start);
-        assert!(repr.is_heap_allocated());
-
-        while repr.len() > 10 {
-            assert!(repr.pop().is_some());
-        }
-        // we don't (yet?) re-inline when characters are popped
-        assert!(repr.is_heap_allocated());
-
-        // extend with one character
-        repr.extend(vec!['!']);
-        // should still be heap allocated
-        assert!(repr.is_heap_allocated());
-
-        // extend with a lot of characters
-        repr.extend((0..100).map(|_| '😊'));
-        // should still be heap allocated
-        assert!(repr.is_heap_allocated());
+    #[should_panic(expected = "Attempted to reserve more than 'usize' bytes")]
+    fn test_reserve_overflow() {
+        let mut r = Repr::new("abc");
+        r.reserve(usize::MAX);
     }
 
-    #[test]
-    fn test_extend_strs() {
-        let example = "hello";
-        let mut repr = Repr::new(example);
+    #[test_case(""; "empty")]
+    #[test_case("abc"; "short")]
+    #[test_case("i am a longer string that will be on the heap"; "long")]
+    #[test_case(EIGHTEEN_MB_STR; "huge")]
+    fn test_clone(initial: &'static str) {
+        let r_a = Repr::new(initial);
+        let r_b = r_a.clone();
 
-        let words = vec![" ", "world!", "my name is", " compact", "_str"];
-        repr.extend(words);
+        assert_eq!(r_a.as_str(), initial);
+        assert_eq!(r_a.len(), initial.len());
 
-        assert_eq!(repr.as_str(), "hello world!my name is compact_str");
-        assert_eq!(repr.len(), 34);
+        assert_eq!(r_a.as_str(), r_b.as_str());
+        assert_eq!(r_a.len(), r_b.len());
+        assert_eq!(r_a.capacity(), r_b.capacity());
+        assert_eq!(r_a.is_heap_allocated(), r_b.is_heap_allocated());
     }
 
-    #[test]
-    fn test_pop_packed() {
-        let mut repr = Repr::new("i am 24 characters long!");
-        repr.pop();
-
-        assert_eq!(repr.len(), 23);
-        assert_eq!(repr.as_str(), "i am 24 characters long");
-    }
+    #[quickcheck]
+    #[cfg_attr(miri, ignore)]
+    fn quickcheck_clone(initial: String) {
+        let r_a = Repr::new(&initial);
+        let r_b = r_a.clone();
 
-    #[test]
-    fn test_pop_does_not_reinline() {
-        let mut repr = Repr::new("i am a long string that will be heap allocated");
-        assert!(repr.is_heap_allocated());
+        assert_eq!(r_a.as_str(), initial);
+        assert_eq!(r_a.len(), initial.len());
 
-        while repr.len() > 10 {
-            repr.pop();
-        }
-        // should not have re-inlined the string
-        assert!(repr.is_heap_allocated());
+        assert_eq!(r_a.as_str(), r_b.as_str());
+        assert_eq!(r_a.len(), r_b.len());
+        assert_eq!(r_a.capacity(), r_b.capacity());
+        assert_eq!(r_a.is_heap_allocated(), r_b.is_heap_allocated());
     }
 
-    #[test]
-    fn test_from_small_string_then_mutate() {
-        let s = String::from("hello world");
-        assert_eq!(s.capacity(), 11);
-
-        let mut repr = Repr::from_string(s);
+    #[test_case("q"; "single")]
+    #[test_case("abc"; "short")]
+    #[test_case("this is (another) long string that will be heap allocated"; "long")]
+    #[test_case(EIGHTEEN_MB_STR; "huge")]
+    fn test_from_box_str(initial: &'static str) {
+        let box_str = String::from(initial).into_boxed_str();
 
-        // When converting from a String, we defer inlining the string until necessary to prevent
-        // dropping the heap allocated buffer
-        assert_eq!(repr.capacity(), 11);
-        assert!(repr.is_heap_allocated());
+        let r = Repr::from_box_str(box_str);
 
-        repr.push_str("!");
+        assert_eq!(r.as_str(), initial);
+        assert_eq!(r.len(), initial.len());
+        assert_eq!(r.capacity(), initial.len());
 
-        // Once we push a character we'll need to resize, it's at this point we'll inline the string
-        // since we need to drop the original buffer anyways
-        assert_eq!(repr.capacity(), MAX_SIZE);
-        assert!(!repr.is_heap_allocated());
-        assert_eq!(repr.as_str(), "hello world!");
+        // when converting from a Box<str> we do not automatically inline the string
+        assert!(r.is_heap_allocated());
     }
 
     #[test]
-    fn test_from_small_box_str_then_mutate() {
-        let b = String::from("hello world").into_boxed_str();
-        assert_eq!(b.len(), 11);
+    fn test_from_box_str_empty() {
+        let box_str = String::from("").into_boxed_str();
 
-        let mut repr = Repr::from_box_str(b);
-
-        // When converting from a Box<str>, we defer inlining the string until necessary to prevent
-        // dropping the heap allocated buffer
-        assert_eq!(repr.capacity(), 11);
-        assert!(repr.is_heap_allocated());
-
-        repr.push_str("!");
-
-        // Once we push a character we'll need to resize, it's at this point we'll inline the string
-        // since we need to drop the original buffer anyways
-        assert_eq!(repr.capacity(), MAX_SIZE);
-        assert!(!repr.is_heap_allocated());
-        assert_eq!(repr.as_str(), "hello world!");
-    }
-
-    #[test]
-    fn test_from_utf8_unchecked_heap_mask() {
-        let bytes = [HEAP_MASK; MAX_SIZE];
+        let r = Repr::from_box_str(box_str);
 
-        // this isn't a valid string, but we should be able to read back the underlying buffer
-        let repr = unsafe { Repr::from_utf8_unchecked(bytes) };
+        assert_eq!(r.as_str(), "");
+        assert_eq!(r.len(), 0);
 
-        assert_eq!(repr.len(), MAX_SIZE);
-        assert_eq!(repr.as_slice(), bytes);
+        // when converting from a Box<str> we do not automatically inline the string, unless the
+        // Box<str> is empty, then we return an empty inlined string
+        assert_eq!(r.capacity(), MAX_SIZE);
+        assert!(!r.is_heap_allocated());
     }
 }
diff --git a/compact_str/src/repr/nonmax.rs b/compact_str/src/repr/nonmax.rs
index eb8090c8..52353a34 100644
--- a/compact_str/src/repr/nonmax.rs
+++ b/compact_str/src/repr/nonmax.rs
@@ -6,6 +6,7 @@
 #[allow(clippy::upper_case_acronyms)]
 #[allow(dead_code)]
 #[allow(non_camel_case_types)]
+#[derive(Copy, Clone, Debug)]
 #[repr(u8)]
 pub enum NonMaxU8 {
     V0 = 0,
@@ -265,4 +266,4 @@ pub enum NonMaxU8 {
     V254 = 254,
 }
 
-crate::asserts::assert_size_eq!(NonMaxU8, Option<NonMaxU8>, u8);
+static_assertions::assert_eq_size!(NonMaxU8, Option<NonMaxU8>, u8);
diff --git a/compact_str/src/repr/num.rs b/compact_str/src/repr/num.rs
index eb51cfc2..c2baa13d 100644
--- a/compact_str/src/repr/num.rs
+++ b/compact_str/src/repr/num.rs
@@ -44,7 +44,7 @@ macro_rules! impl_IntoRepr {
                 // our string will end up being num_digits long
                 unsafe { repr.set_len(num_digits) };
                 // get mutable pointer to our buffer
-                let buf_ptr = unsafe { repr.as_mut_slice().as_mut_ptr() };
+                let buf_ptr = unsafe { repr.as_mut_buf().as_mut_ptr() };
 
                 let lut_ptr = DEC_DIGITS_LUT.as_ptr();
 
diff --git a/compact_str/src/repr/traits.rs b/compact_str/src/repr/traits.rs
index 8dfcf6dd..b75b91cf 100644
--- a/compact_str/src/repr/traits.rs
+++ b/compact_str/src/repr/traits.rs
@@ -43,8 +43,7 @@ impl IntoRepr for char {
 
 #[cfg(test)]
 mod tests {
-    use proptest::prelude::*;
-    use test_strategy::proptest;
+    use quickcheck_macros::quickcheck;
 
     use super::IntoRepr;
 
@@ -59,11 +58,11 @@ mod tests {
         assert_eq!(repr.as_str(), f.to_string());
     }
 
-    #[proptest]
+    #[quickcheck]
     #[cfg_attr(miri, ignore)]
-    fn proptest_into_repr_char(val: char) {
+    fn quickcheck_into_repr_char(val: char) {
         let repr = char::into_repr(val);
-        prop_assert_eq!(repr.as_str(), val.to_string());
+        assert_eq!(repr.as_str(), val.to_string());
     }
 
     #[test]
@@ -91,16 +90,18 @@ mod tests {
         assert!(roundtrip.is_nan());
     }
 
-    #[proptest]
+    #[quickcheck]
     #[cfg_attr(miri, ignore)]
-    fn proptest_into_repr_f64(val: f64) {
+    fn quickcheck_into_repr_f64(val: f64) {
         let repr = f64::into_repr(val);
         let roundtrip = repr.as_str().parse::<f64>().unwrap();
 
         // Note: The formatting of floats by `ryu` sometimes differs from that of `std`, so instead
         // of asserting equality with `std` we just make sure the value roundtrips
 
-        prop_assert_eq!(val, roundtrip);
+        if val.is_nan() != roundtrip.is_nan() {
+            assert_eq!(val, roundtrip);
+        }
     }
 
     // `f32` formatting is broken on powerpc64le, not only in `ryu` but also `std`
@@ -133,8 +134,7 @@ mod tests {
         assert!(roundtrip.is_nan());
     }
 
-    #[proptest]
-    #[cfg_attr(miri, ignore)]
+    #[quickcheck]
     #[cfg_attr(all(target_arch = "powerpc64", target_pointer_width = "64"), ignore)]
     fn proptest_into_repr_f32(val: f32) {
         let repr = f32::into_repr(val);
@@ -143,6 +143,8 @@ mod tests {
         // Note: The formatting of floats by `ryu` sometimes differs from that of `std`, so instead
         // of asserting equality with `std` we just make sure the value roundtrips
 
-        prop_assert_eq!(val, roundtrip);
+        if val.is_nan() != roundtrip.is_nan() {
+            assert_eq!(val, roundtrip);
+        }
     }
 }
diff --git a/compact_str/src/traits.rs b/compact_str/src/traits.rs
index 7e51ec79..f5f1ae8d 100644
--- a/compact_str/src/traits.rs
+++ b/compact_str/src/traits.rs
@@ -102,15 +102,15 @@ impl<T: fmt::Display> ToCompactString for T {
             &num::NonZeroI128 as s => s.into_repr(),
             s => {
                 let num_bytes = count(s);
-                let mut repr = Repr::with_capacity(num_bytes);
+                let mut c = CompactString::with_capacity(num_bytes);
 
-                write!(&mut repr, "{}", s).expect("fmt::Display incorrectly implemented!");
+                write!(&mut c, "{}", s).expect("fmt::Display incorrectly implemented!");
 
-                repr
+                return c;
             }
         });
 
-        CompactString { repr }
+        CompactString(repr)
     }
 }
 
diff --git a/fuzz/src/creation.rs b/fuzz/src/creation.rs
index 0deff4db..e1d9c70a 100644
--- a/fuzz/src/creation.rs
+++ b/fuzz/src/creation.rs
@@ -16,7 +16,10 @@ use compact_str::{
 };
 
 use super::assert_properly_allocated;
-use crate::MAX_INLINE_LENGTH;
+use crate::{
+    MAX_INLINE_LENGTH,
+    MIN_HEAP_CAPACITY,
+};
 
 #[derive(Arbitrary, Debug)]
 pub enum Creation<'a> {
@@ -690,8 +693,12 @@ impl Creation<'_> {
                 let std_str = String::with_capacity(num_bytes as usize);
 
                 if compact.is_heap_allocated() {
-                    // if we're heap allocated, then we should have the same capacity
-                    assert_eq!(compact.capacity(), std_str.capacity());
+                    if std_str.capacity() <= MIN_HEAP_CAPACITY {
+                        assert_eq!(compact.capacity(), MIN_HEAP_CAPACITY);
+                    } else {
+                        // if we're heap allocated, then we should have the same capacity
+                        assert_eq!(compact.capacity(), std_str.capacity());
+                    }
                 } else {
                     // if we're inline then a CompactString will have capacity MAX_INLINE_LENGTH
                     assert!(num_bytes as usize <= super::MAX_INLINE_LENGTH);
diff --git a/fuzz/src/lib.rs b/fuzz/src/lib.rs
index 10845ddc..bc5c5714 100644
--- a/fuzz/src/lib.rs
+++ b/fuzz/src/lib.rs
@@ -14,6 +14,7 @@ use arbitrary::Arbitrary;
 use compact_str::CompactString;
 
 const MAX_INLINE_LENGTH: usize = std::mem::size_of::<String>();
+const MIN_HEAP_CAPACITY: usize = std::mem::size_of::<usize>() * 4;
 const TWENTY_FOUR_MB_AS_BYTES: usize = 24 * 1024 * 1024;
 
 mod actions;


Test patch:
diff --git a/compact_str/src/tests.rs b/compact_str/src/tests.rs
index 171478f5..4d5f47ab 100644
--- a/compact_str/src/tests.rs
+++ b/compact_str/src/tests.rs
@@ -36,20 +36,6 @@ pub fn rand_u16s() -> impl Strategy<Value = Vec<u16>> {
     proptest::collection::vec(any::<u16>(), 0..80)
 }
 
-/// [`proptest::strategy::Strategy`] that generates [`String`]s with up to `len` bytes
-pub fn rand_unicode_with_max_len(len: usize) -> impl Strategy<Value = String> {
-    proptest::collection::vec(proptest::char::any(), 0..len).prop_map(move |chars| {
-        let mut len_utf8 = 0;
-        chars
-            .into_iter()
-            .take_while(|c| {
-                len_utf8 += c.len_utf8();
-                len_utf8 <= len
-            })
-            .collect::<String>()
-    })
-}
-
 /// [`proptest::strategy::Strategy`] that generates [`String`]s with up to `len` bytes
 pub fn rand_unicode_with_range(range: impl Into<SizeRange>) -> impl Strategy<Value = String> {
     proptest::collection::vec(proptest::char::any(), range).prop_map(|v| v.into_iter().collect())
@@ -997,7 +983,7 @@ fn test_into_string_small_str() {
 
 #[test]
 fn test_into_string_long_str() {
-    let data = "abcdefghijklmnopqrstuvwxyz";
+    let data = "this is a long string that will be on the heap";
     let str_addr = data.as_ptr();
     let str_len = data.len();