flexible_string/
lib.rs

1//! A stack heap flexible string designed to improve performance.
2//!
3//! [`FlexibleString`] has a fixed stack buffer of the given bytes, and
4//! automatically upgrades to [`String`] when more space is needed. It provides
5//! APIs that are as consistent as possible with [`String`], but some APIs are
6//! not yet implemented or cannot be implemented.
7//!
8//! [`FlexibleString`] was first implemented in [spdlog-rs] crate, which
9//! improved performance for [spdlog-rs] by about double
10//! (see [benchmarks of spdlog-rs]). Now it is extracted to a separate crate for
11//! use by other crates.
12//!
13//! # Benchmarks
14//!
15//! See [section Benchmarks] of the README for this repository.
16//!
17//! # Examples
18//!
19//! ```
20//! use flexible_string::FlexibleString;
21//!
22//! let mut string = FlexibleString::<250>::from("hello");
23//! string.push(',');
24//! string.push_str("world");
25//! assert_eq!(string, "hello,world");
26//! ```
27//!
28//! [spdlog-rs]: https://crates.io/crates/spdlog-rs
29//! [benchmarks of spdlog-rs]: https://github.com/SpriteOvO/spdlog-rs#benchmarks
30//! [section Benchmarks]: https://github.com/SpriteOvO/flexible-string#benchmarks
31
32#![warn(missing_docs)]
33
34use std::{ffi::OsStr, fmt, mem::MaybeUninit, ops, ptr, slice, str, string};
35
36// The following implementations are referenced from :
37// https://github.com/rust-lang/rust/blob/f1edd0429582dd29cccacaf50fd134b05593bd9c/library/alloc/src/string.rs
38
39/// A possible error value when converting a `FlexibleString` from a UTF-8 byte vector.
40///
41/// This type is the error type for the [`from_utf8`] method on [`FlexibleString`]. It
42/// is designed in such a way to carefully avoid reallocations: the
43/// [`into_bytes`] method will give back the byte vector that was used in the
44/// conversion attempt.
45///
46/// [`from_utf8`]: FlexibleString::from_utf8
47/// [`into_bytes`]: FromUtf8Error::into_bytes
48///
49/// The [`Utf8Error`] type provided by [`std::str`] represents an error that may
50/// occur when converting a slice of [`u8`]s to a [`&str`]. In this sense, it's
51/// an analogue to `FromUtf8Error`, and you can get one from a `FromUtf8Error`
52/// through the [`utf8_error`] method.
53///
54/// [`Utf8Error`]: str::Utf8Error "std::str::Utf8Error"
55/// [`std::str`]: core::str "std::str"
56/// [`&str`]: prim@str "&str"
57/// [`utf8_error`]: FromUtf8Error::utf8_error
58///
59/// # Examples
60///
61/// Basic usage:
62///
63/// ```
64/// use flexible_string::FlexibleString;
65///
66/// // some invalid bytes, in a vector
67/// let bytes = vec![0, 159];
68///
69/// let value = FlexibleString::<200>::from_utf8(bytes);
70///
71/// assert!(value.is_err());
72/// assert_eq!(vec![0, 159], value.unwrap_err().into_bytes());
73/// ```
74// We implement it manually because the fields in std are private.
75#[derive(Clone, Debug, PartialEq, Eq)]
76pub struct FromUtf8Error {
77    bytes: Vec<u8>,
78    error: str::Utf8Error,
79}
80
81/// A stack heap flexible string, which first uses a fixed size stack buffer of
82/// `CAPACITY` bytes and automatically upgrades to a heap buffer (`String`)
83/// when more space is needed.
84///
85/// It provides APIs that are as consistent as possible with `String`, but
86/// some APIs are not yet implemented or cannot be implemented. For implemented
87/// methods, the documentation and examples of standard `String` apply to it as
88/// well.
89#[derive(Clone)]
90pub struct FlexibleString<const CAPACITY: usize>(FlexibleStringInner<CAPACITY>);
91
92#[derive(Clone)]
93enum FlexibleStringInner<const CAPACITY: usize> {
94    Stack(StackString<CAPACITY>),
95    Heap(String),
96}
97
98macro_rules! common_methods_inner {
99    (NEVER_UPGRADE => fn_name:$fn_name:ident, generics:$(<$generics:tt>)?, self_qual:$([$($self_qual:tt)*])?, self:$self:ident, arg_name:[$($arg_name:ident),*]) => {
100        match $($($self_qual)*)? $self.0 {
101            FlexibleStringInner::Stack(s) => s.$fn_name $(::<$generics>)? ($($arg_name),*),
102            FlexibleStringInner::Heap(h) => h.$fn_name $(::<$generics>)? ($($arg_name),*),
103        }
104    };
105    (MAYBE_UPGRADE => fn_name:$fn_name:ident, generics:$(<$generics:tt>)?, self_qual:$([$($self_qual:tt)*])?, self:$self:ident, arg_name:[$($arg_name:ident),*]) => {
106        match $($($self_qual)*)? $self.0 {
107            FlexibleStringInner::Stack(s) => {
108                match s.$fn_name $(::<$generics>)? ($($arg_name),*) {
109                    Err(capacity) => {
110                        let mut heap = s.to_heap(capacity);
111                        let res = heap.$fn_name($($arg_name),*);
112                        *$self = Self(FlexibleStringInner::Heap(heap));
113                        res
114                    },
115                    Ok(res) => res
116                }
117            },
118            FlexibleStringInner::Heap(h) => h.$fn_name $(::<$generics>)? ($($arg_name),*),
119        }
120    };
121}
122
123macro_rules! common_methods {
124    () => {};
125    ( $(#[$attr:meta])*
126    $upgrade:ident => $vis:vis $([$($qual:tt)*])? fn $fn_name:ident $(<$generics:tt>)? ( $([$($self_qual:tt)*])? $self:ident $(,)? $( $arg_name:ident: $arg_type:ty),* ) $(-> $ret:ty)?
127    $(where $($where_ty:ty: $where_bound:path)*)?; $($tail:tt)* ) => {
128        $(#[$attr])*
129        #[inline]
130        $vis $($($qual)*)? fn $fn_name $(<$generics>)? ($($($self_qual)*)? $self, $($arg_name: $arg_type),*) $(-> $ret)?
131        $(where $($where_ty: $where_bound)*)? {
132            common_methods_inner!($upgrade => fn_name:$fn_name, generics:$(<$generics>)?, self_qual:$([$($self_qual)*])?, self:$self, arg_name:[$($arg_name),*])
133        }
134        common_methods!($($tail)*);
135    };
136}
137
138impl<const CAPACITY: usize> FlexibleString<CAPACITY> {
139    /// Creates a new empty `FlexibleString`.
140    ///
141    /// # Examples
142    ///
143    /// Basic usage:
144    ///
145    /// ```
146    /// use flexible_string::FlexibleString;
147    ///
148    /// let s = FlexibleString::<200>::new();
149    /// ```
150    #[inline]
151    #[must_use]
152    pub fn new() -> Self {
153        Self(FlexibleStringInner::Stack(StackString::new()))
154    }
155
156    /// Creates a new empty `FlexibleString` with a particular capacity.
157    ///
158    /// # Examples
159    ///
160    /// Basic usage:
161    ///
162    /// ```
163    /// use flexible_string::FlexibleString;
164    ///
165    /// let mut s = FlexibleString::<200>::with_capacity(10);
166    ///
167    /// // The FlexibleString contains no chars, even though it has capacity for more
168    /// assert_eq!(s.len(), 0);
169    ///
170    /// // These are all done without reallocating...
171    /// let cap = s.capacity();
172    /// for _ in 0..10 {
173    ///     s.push('a');
174    /// }
175    ///
176    /// assert_eq!(s.capacity(), cap);
177    ///
178    /// // ...but this may make the string reallocate
179    /// s.push('a');
180    /// ```
181    #[inline]
182    #[must_use]
183    pub fn with_capacity(capacity: usize) -> Self {
184        if capacity > CAPACITY {
185            Self(FlexibleStringInner::Heap(String::with_capacity(capacity)))
186        } else {
187            Self(FlexibleStringInner::Stack(StackString::new()))
188        }
189    }
190
191    /// Converts a vector of bytes to a `FlexibleString`.
192    ///
193    /// # Examples
194    ///
195    /// Basic usage:
196    ///
197    /// ```
198    /// use flexible_string::FlexibleString;
199    ///
200    /// // some bytes, in a vector
201    /// let sparkle_heart = vec![240, 159, 146, 150];
202    ///
203    /// // We know these bytes are valid, so we'll use `unwrap()`.
204    /// let sparkle_heart = FlexibleString::<200>::from_utf8(sparkle_heart).unwrap();
205    ///
206    /// assert_eq!("💖", sparkle_heart);
207    /// ```
208    ///
209    /// Incorrect bytes:
210    ///
211    /// ```
212    /// use flexible_string::FlexibleString;
213    ///
214    /// // some invalid bytes, in a vector
215    /// let sparkle_heart = vec![0, 159, 146, 150];
216    ///
217    /// assert!(FlexibleString::<200>::from_utf8(sparkle_heart).is_err());
218    /// ```
219    #[inline]
220    pub fn from_utf8(vec: Vec<u8>) -> Result<Self, FromUtf8Error> {
221        if vec.len() > CAPACITY {
222            String::from_utf8(vec)
223                .map(|s| Self(FlexibleStringInner::Heap(s)))
224                .map_err(|err| err.into())
225        } else {
226            unsafe { StackString::from_utf8_vec_only_len_unchecked(vec) }
227                .map(|s| Self(FlexibleStringInner::Stack(s)))
228        }
229    }
230
231    // Unimplemented.
232    // pub fn from_utf8_lossy(v: &[u8]) -> Cow<'_, str> {}
233
234    // Unimplemented.
235    // pub fn from_utf16(v: &[u16]) -> Result<Self, FromUtf16Error> {}
236
237    // Unimplemented.
238    // pub fn from_utf16_lossy(v: &[u16]) -> Self {}
239
240    // Unimplemented since unstable.
241    // pub fn into_raw_parts(self) -> (*mut u8, usize, usize)
242
243    // Unimplemented since unstable.
244    // pub unsafe fn from_raw_parts(buf: *mut u8, length: usize, capacity: usize) -> String
245
246    /// Converts a vector of bytes to a `FlexibleString` without checking that the
247    /// string contains valid UTF-8.
248    ///
249    /// # Safety
250    ///
251    /// See the documentation of [`String::from_utf8_unchecked`].
252    ///
253    /// # Examples
254    ///
255    /// Basic usage:
256    ///
257    /// ```
258    /// use flexible_string::FlexibleString;
259    ///
260    /// // some bytes, in a vector
261    /// let sparkle_heart = vec![240, 159, 146, 150];
262    ///
263    /// let sparkle_heart = unsafe {
264    ///     FlexibleString::<200>::from_utf8_unchecked(sparkle_heart)
265    /// };
266    ///
267    /// assert_eq!("💖", sparkle_heart);
268    /// ```
269    #[inline]
270    #[must_use]
271    pub unsafe fn from_utf8_unchecked(bytes: Vec<u8>) -> Self {
272        if bytes.len() > CAPACITY {
273            Self(FlexibleStringInner::Heap(String::from_utf8_unchecked(
274                bytes,
275            )))
276        } else {
277            Self(FlexibleStringInner::Stack(
278                StackString::from_utf8_slice_unchecked(&bytes),
279            ))
280        }
281    }
282
283    common_methods! {
284        /// Converts a `FlexibleString` into a byte vector.
285        ///
286        /// # Examples
287        ///
288        /// Basic usage:
289        ///
290        /// ```
291        /// use flexible_string::FlexibleString;
292        ///
293        /// let s = FlexibleString::<200>::from("hello");
294        /// let bytes = s.into_bytes();
295        ///
296        /// assert_eq!(&[104, 101, 108, 108, 111][..], &bytes[..]);
297        /// ```
298        #[must_use = "`self` will be dropped if the result is not used"]
299        NEVER_UPGRADE => pub fn into_bytes(self) -> Vec<u8>;
300
301        /// Extracts a string slice containing the entire `FlexibleString`.
302        ///
303        /// # Examples
304        ///
305        /// Basic usage:
306        ///
307        /// ```
308        /// use flexible_string::FlexibleString;
309        ///
310        /// let s = FlexibleString::<200>::from("foo");
311        ///
312        /// assert_eq!("foo", s.as_str());
313        /// ```
314        #[must_use]
315        NEVER_UPGRADE => pub fn as_str([&]self) -> &str;
316
317        /// Converts a `FlexibleString` into a mutable string slice.
318        ///
319        /// # Examples
320        ///
321        /// Basic usage:
322        ///
323        /// ```
324        /// use flexible_string::FlexibleString;
325        ///
326        /// let mut s = FlexibleString::<200>::from("foobar");
327        /// let s_mut_str = s.as_mut_str();
328        ///
329        /// s_mut_str.make_ascii_uppercase();
330        ///
331        /// assert_eq!("FOOBAR", s_mut_str);
332        /// ```
333        #[must_use]
334        NEVER_UPGRADE => pub fn as_mut_str([&mut]self) -> &mut str;
335
336        /// Appends a given string slice onto the end of this `FlexibleString`.
337        ///
338        /// # Examples
339        ///
340        /// Basic usage:
341        ///
342        /// ```
343        /// use flexible_string::FlexibleString;
344        ///
345        /// let mut s = FlexibleString::<200>::from("foo");
346        ///
347        /// s.push_str("bar");
348        ///
349        /// assert_eq!("foobar", s);
350        /// ```
351        MAYBE_UPGRADE => pub fn push_str([&mut]self, string: &str);
352
353        // Unimplemented since unstable.
354        // pub fn extend_from_within<R>(&mut self, src: R)
355
356        /// Returns this `FlexibleString`'s capacity, in bytes.
357        ///
358        /// # Examples
359        ///
360        /// Basic usage:
361        ///
362        /// ```
363        /// use flexible_string::FlexibleString;
364        ///
365        /// let s = FlexibleString::<200>::with_capacity(10);
366        ///
367        /// assert!(s.capacity() >= 10);
368        /// ```
369        NEVER_UPGRADE => pub fn capacity([&]self) -> usize;
370
371        /// Ensures that this `FlexibleString`'s capacity is at least `additional` bytes
372        /// larger than its length.
373        ///
374        /// # Examples
375        ///
376        /// Basic usage:
377        ///
378        /// ```
379        /// use flexible_string::FlexibleString;
380        ///
381        /// let mut s = FlexibleString::<200>::new();
382        ///
383        /// s.reserve(10);
384        ///
385        /// assert!(s.capacity() >= 10);
386        /// ```
387        ///
388        /// This might not actually increase the capacity:
389        ///
390        /// ```
391        /// use flexible_string::FlexibleString;
392        ///
393        /// let mut s = FlexibleString::<200>::with_capacity(10);
394        /// s.push('a');
395        /// s.push('b');
396        ///
397        /// // s now has a length of 2 and a capacity of 10
398        /// assert_eq!(2, s.len());
399        /// assert!(s.capacity() >= 10);
400        ///
401        /// // Since we already have an extra 8 capacity, calling this...
402        /// s.reserve(8);
403        ///
404        /// // ... doesn't actually increase.
405        /// assert!(s.capacity() >= 10);
406        /// ```
407        MAYBE_UPGRADE => pub fn reserve([&mut]self, additional: usize);
408
409        /// Ensures that this `FlexibleString`'s capacity is `additional` bytes
410        /// larger than its length.
411        ///
412        /// # Examples
413        ///
414        /// Basic usage:
415        ///
416        /// ```
417        /// use flexible_string::FlexibleString;
418        ///
419        /// let mut s = FlexibleString::<200>::new();
420        ///
421        /// s.reserve_exact(10);
422        ///
423        /// assert!(s.capacity() >= 10);
424        /// ```
425        ///
426        /// This might not actually increase the capacity:
427        ///
428        /// ```
429        /// use flexible_string::FlexibleString;
430        ///
431        /// let mut s = FlexibleString::<200>::with_capacity(10);
432        /// s.push('a');
433        /// s.push('b');
434        ///
435        /// // s now has a length of 2 and a capacity of 10
436        /// assert_eq!(2, s.len());
437        /// assert!(s.capacity() >= 10);
438        ///
439        /// // Since we already have an extra 8 capacity, calling this...
440        /// s.reserve_exact(8);
441        ///
442        /// // ... doesn't actually increase.
443        /// assert!(s.capacity() >= 10);
444        /// ```
445        MAYBE_UPGRADE => pub fn reserve_exact([&mut]self, additional: usize);
446
447        // Unimplemented since `TryReserveErrorKind` is currently unstable.
448        //
449        // /// Tries to reserve capacity for at least `additional` more elements to be inserted
450        // /// in the given `FlexibleString`. The collection may reserve more space to avoid
451        // /// frequent reallocations. After calling `reserve`, capacity will be
452        // /// greater than or equal to `self.len() + additional`. Does nothing if
453        // /// capacity is already sufficient.
454        // ///
455        // /// # Examples
456        // ///
457        // /// ```
458        // /// use flexible_string::FlexibleString;
459        // ///
460        // /// use std::collections::TryReserveError;
461        // ///
462        // /// fn process_data(data: &str) -> Result<FlexibleString::<200>, TryReserveError> {
463        // ///     let mut output = FlexibleString::<200>::new();
464        // ///
465        // ///     // Pre-reserve the memory, exiting if we can't
466        // ///     output.try_reserve(data.len())?;
467        // ///
468        // ///     // Now we know this can't OOM in the middle of our complex work
469        // ///     output.push_str(data);
470        // ///
471        // ///     Ok(output)
472        // /// }
473        // /// # process_data("rust").expect("why is the test harness OOMing on 4 bytes?");
474        // /// ```
475        // MAYBE_UPGRADE => pub fn try_reserve([&mut]self, additional: usize) -> Result<(), TryReserveError>;
476        //
477        // /// Tries to reserve the minimum capacity for exactly `additional` more elements to
478        // /// be inserted in the given `FlexibleString`. After calling `reserve_exact`,
479        // /// capacity will be greater than or equal to `self.len() + additional`.
480        // /// Does nothing if the capacity is already sufficient.
481        // ///
482        // /// # Examples
483        // ///
484        // /// ```
485        // /// use flexible_string::FlexibleString;
486        // ///
487        // /// use std::collections::TryReserveError;
488        // ///
489        // /// fn process_data(data: &str) -> Result<FlexibleString::<200>, TryReserveError> {
490        // ///     let mut output = FlexibleString::<200>::new();
491        // ///
492        // ///     // Pre-reserve the memory, exiting if we can't
493        // ///     output.try_reserve_exact(data.len())?;
494        // ///
495        // ///     // Now we know this can't OOM in the middle of our complex work
496        // ///     output.push_str(data);
497        // ///
498        // ///     Ok(output)
499        // /// }
500        // /// # process_data("rust").expect("why is the test harness OOMing on 4 bytes?");
501        // /// ```
502        // MAYBE_UPGRADE => pub fn try_reserve_exact([&mut]self, additional: usize) -> Result<(), TryReserveError>;
503
504        // Cannot be implemented because the stack string cannot ensure the requirement.
505        // pub fn shrink_to_fit(&mut self);
506
507        /// Shrinks the capacity of this `FlexibleString` with a lower bound.
508        ///
509        /// # Examples
510        ///
511        /// ```
512        /// use flexible_string::FlexibleString;
513        ///
514        /// let mut s = FlexibleString::<200>::from("foo");
515        ///
516        /// s.reserve(100);
517        /// assert!(s.capacity() >= 100);
518        ///
519        /// s.shrink_to(10);
520        /// assert!(s.capacity() >= 10);
521        /// s.shrink_to(0);
522        /// assert!(s.capacity() >= 3);
523        /// ```
524        NEVER_UPGRADE => pub fn shrink_to([&mut]self, min_capacity: usize);
525
526        /// Appends the given [`char`] to the end of this `FlexibleString`.
527        ///
528        /// # Examples
529        ///
530        /// Basic usage:
531        ///
532        /// ```
533        /// use flexible_string::FlexibleString;
534        ///
535        /// let mut s = FlexibleString::<200>::from("abc");
536        ///
537        /// s.push('1');
538        /// s.push('2');
539        /// s.push('3');
540        ///
541        /// assert_eq!("abc123", s);
542        /// ```
543        MAYBE_UPGRADE => pub fn push([&mut]self, ch: char);
544
545        /// Returns a byte slice of this `FlexibleString`'s contents.
546        ///
547        /// # Examples
548        ///
549        /// Basic usage:
550        ///
551        /// ```
552        /// use flexible_string::FlexibleString;
553        ///
554        /// let s = FlexibleString::<200>::from("hello");
555        ///
556        /// assert_eq!(&[104, 101, 108, 108, 111], s.as_bytes());
557        /// ```
558        #[must_use]
559        NEVER_UPGRADE => pub fn as_bytes([&]self) -> &[u8];
560
561        /// Shortens this `FlexibleString` to the specified length.
562        ///
563        /// If `new_len` is greater than the string's current length, this has no
564        /// effect.
565        ///
566        /// Note that this method has no effect on the allocated capacity
567        /// of the string
568        ///
569        /// # Panics
570        ///
571        /// Panics if `new_len` does not lie on a [`char`] boundary.
572        ///
573        /// # Examples
574        ///
575        /// Basic usage:
576        ///
577        /// ```
578        /// use flexible_string::FlexibleString;
579        ///
580        /// let mut s = FlexibleString::<200>::from("hello");
581        ///
582        /// s.truncate(2);
583        ///
584        /// assert_eq!("he", s);
585        /// ```
586        NEVER_UPGRADE => pub fn truncate([&mut]self, new_len: usize);
587
588        /// Removes the last character from the string buffer and returns it.
589        ///
590        /// Returns [`None`] if this `FlexibleString` is empty.
591        ///
592        /// # Examples
593        ///
594        /// Basic usage:
595        ///
596        /// ```
597        /// use flexible_string::FlexibleString;
598        ///
599        /// let mut s = FlexibleString::<200>::from("foo");
600        ///
601        /// assert_eq!(s.pop(), Some('o'));
602        /// assert_eq!(s.pop(), Some('o'));
603        /// assert_eq!(s.pop(), Some('f'));
604        ///
605        /// assert_eq!(s.pop(), None);
606        /// ```
607        NEVER_UPGRADE => pub fn pop([&mut]self) -> Option<char>;
608
609        /// Removes a [`char`] from this `FlexibleString` at a byte position and returns it.
610        ///
611        /// This is an *O*(*n*) operation, as it requires copying every element in the
612        /// buffer.
613        ///
614        /// # Panics
615        ///
616        /// Panics if `idx` is larger than or equal to the `FlexibleString`'s length,
617        /// or if it does not lie on a [`char`] boundary.
618        ///
619        /// # Examples
620        ///
621        /// Basic usage:
622        ///
623        /// ```
624        /// use flexible_string::FlexibleString;
625        ///
626        /// let mut s = FlexibleString::<200>::from("foo");
627        ///
628        /// assert_eq!(s.remove(0), 'f');
629        /// assert_eq!(s.remove(1), 'o');
630        /// assert_eq!(s.remove(0), 'o');
631        /// ```
632        NEVER_UPGRADE => pub fn remove([&mut]self, idx: usize) -> char;
633
634        // Unimplemented.
635        // ...
636
637        /// Inserts a character into this `FlexibleString` at a byte position.
638        ///
639        /// This is an *O*(*n*) operation as it requires copying every element in the
640        /// buffer.
641        ///
642        /// # Panics
643        ///
644        /// Panics if `idx` is larger than the `FlexibleString`'s length, or if it does not
645        /// lie on a [`char`] boundary.
646        ///
647        /// # Examples
648        ///
649        /// Basic usage:
650        ///
651        /// ```
652        /// use flexible_string::FlexibleString;
653        ///
654        /// let mut s = FlexibleString::<200>::with_capacity(3);
655        ///
656        /// s.insert(0, 'f');
657        /// s.insert(1, 'o');
658        /// s.insert(2, 'o');
659        ///
660        /// assert_eq!("foo", s);
661        /// ```
662        MAYBE_UPGRADE => pub fn insert([&mut]self, idx: usize, ch: char);
663
664        /// Inserts a string slice into this `FlexibleString` at a byte position.
665        ///
666        /// This is an *O*(*n*) operation as it requires copying every element in the
667        /// buffer.
668        ///
669        /// # Panics
670        ///
671        /// Panics if `idx` is larger than the `FlexibleString`'s length, or if it does not
672        /// lie on a [`char`] boundary.
673        ///
674        /// # Examples
675        ///
676        /// Basic usage:
677        ///
678        /// ```
679        /// use flexible_string::FlexibleString;
680        ///
681        /// let mut s = FlexibleString::<200>::from("bar");
682        ///
683        /// s.insert_str(0, "foo");
684        ///
685        /// assert_eq!("foobar", s);
686        /// ```
687        MAYBE_UPGRADE => pub fn insert_str([&mut]self, idx: usize, string: &str);
688
689        // Unimplemented.
690        // pub unsafe fn as_mut_vec(&mut self) -> &mut Vec<u8>
691
692        /// Returns the length of this `FlexibleString`, in bytes, not [`char`]s or
693        /// graphemes. In other words, it might not be what a human considers the
694        /// length of the string.
695        ///
696        /// # Examples
697        ///
698        /// Basic usage:
699        ///
700        /// ```
701        /// use flexible_string::FlexibleString;
702        ///
703        /// let a = FlexibleString::<200>::from("foo");
704        /// assert_eq!(a.len(), 3);
705        ///
706        /// let fancy_f = FlexibleString::<200>::from("Æ’oo");
707        /// assert_eq!(fancy_f.len(), 4);
708        /// assert_eq!(fancy_f.chars().count(), 3);
709        /// ```
710        NEVER_UPGRADE => pub fn len([&]self) -> usize;
711
712        /// Returns `true` if this `FlexibleString` has a length of zero, and `false` otherwise.
713        ///
714        /// # Examples
715        ///
716        /// Basic usage:
717        ///
718        /// ```
719        /// use flexible_string::FlexibleString;
720        ///
721        /// let mut v = FlexibleString::<200>::new();
722        /// assert!(v.is_empty());
723        ///
724        /// v.push('a');
725        /// assert!(!v.is_empty());
726        /// ```
727        NEVER_UPGRADE => pub fn is_empty([&]self) -> bool;
728
729        // Unimplemented.
730        // pub fn split_off(&mut self, at: usize) -> String;
731
732        /// Truncates this `FlexibleString`, removing all contents.
733        ///
734        /// While this means the `FlexibleString` will have a length of zero, it does not
735        /// touch its capacity.
736        ///
737        /// # Examples
738        ///
739        /// Basic usage:
740        ///
741        /// ```
742        /// use flexible_string::FlexibleString;
743        ///
744        /// let mut s = FlexibleString::<200>::from("foo");
745        ///
746        /// s.clear();
747        ///
748        /// assert!(s.is_empty());
749        /// assert_eq!(0, s.len());
750        /// ```
751        NEVER_UPGRADE => pub fn clear([&mut]self);
752
753        // Unimplemented.
754        // pub fn drain<R>(&mut self, range: R) -> Drain<'_>;
755
756        // Unimplemented.
757        // ...
758    }
759}
760
761impl<const CAPACITY: usize> Default for FlexibleString<CAPACITY> {
762    #[inline]
763    fn default() -> Self {
764        Self::new()
765    }
766}
767
768macro_rules! impl_eq {
769    ($lhs:ty, $rhs:ty) => {
770        #[allow(unused_lifetimes)]
771        impl<'a, 'b, const CAPACITY: usize> PartialEq<$rhs> for $lhs {
772            #[inline]
773            fn eq(&self, other: &$rhs) -> bool {
774                PartialEq::eq(&self[..], &other[..])
775            }
776        }
777
778        #[allow(unused_lifetimes)]
779        impl<'a, 'b, const CAPACITY: usize> PartialEq<$lhs> for $rhs {
780            #[inline]
781            fn eq(&self, other: &$lhs) -> bool {
782                PartialEq::eq(&self[..], &other[..])
783            }
784        }
785    };
786}
787
788impl_eq! { FlexibleString<CAPACITY>, str }
789impl_eq! { FlexibleString<CAPACITY>, &'a str }
790impl_eq! { FlexibleString<CAPACITY>, String }
791
792impl<const CAPACITY_LHS: usize, const CAPACITY_RHS: usize> PartialEq<FlexibleString<CAPACITY_RHS>>
793    for FlexibleString<CAPACITY_LHS>
794{
795    #[inline]
796    fn eq(&self, other: &FlexibleString<CAPACITY_RHS>) -> bool {
797        PartialEq::eq(&self[..], &other[..])
798    }
799}
800
801impl<const CAPACITY: usize> AsRef<str> for FlexibleString<CAPACITY> {
802    #[inline]
803    fn as_ref(&self) -> &str {
804        self
805    }
806}
807
808impl<const CAPACITY: usize> AsMut<str> for FlexibleString<CAPACITY> {
809    #[inline]
810    fn as_mut(&mut self) -> &mut str {
811        self
812    }
813}
814
815impl<const CAPACITY: usize> AsRef<[u8]> for FlexibleString<CAPACITY> {
816    #[inline]
817    fn as_ref(&self) -> &[u8] {
818        self.as_bytes()
819    }
820}
821
822impl<const CAPACITY: usize> AsRef<OsStr> for FlexibleString<CAPACITY> {
823    #[inline]
824    fn as_ref(&self) -> &OsStr {
825        (&**self).as_ref()
826    }
827}
828
829impl<const CAPACITY: usize> From<char> for FlexibleString<CAPACITY> {
830    #[inline]
831    fn from(c: char) -> Self {
832        FlexibleString::from(c.encode_utf8(&mut [0; 4]))
833    }
834}
835
836impl<const CAPACITY: usize> From<&str> for FlexibleString<CAPACITY> {
837    #[inline]
838    fn from(s: &str) -> Self {
839        let bytes = s.as_bytes();
840        if bytes.len() > CAPACITY {
841            let owned_bytes = bytes.to_owned();
842            Self(FlexibleStringInner::Heap(unsafe {
843                String::from_utf8_unchecked(owned_bytes)
844            }))
845        } else {
846            Self(FlexibleStringInner::Stack(unsafe {
847                StackString::from_utf8_slice_unchecked(bytes)
848            }))
849        }
850    }
851}
852
853impl<const CAPACITY: usize> From<&mut str> for FlexibleString<CAPACITY> {
854    #[inline]
855    fn from(s: &mut str) -> Self {
856        (s as &str).into()
857    }
858}
859
860impl<const CAPACITY: usize> From<String> for FlexibleString<CAPACITY> {
861    #[inline]
862    fn from(s: String) -> Self {
863        s.as_str().into()
864    }
865}
866
867impl<'a, const CAPACITY: usize> FromIterator<&'a char> for FlexibleString<CAPACITY> {
868    fn from_iter<I: IntoIterator<Item = &'a char>>(iter: I) -> Self {
869        let mut buf = FlexibleString::new();
870        buf.extend(iter);
871        buf
872    }
873}
874
875impl<'a, const CAPACITY: usize> FromIterator<&'a str> for FlexibleString<CAPACITY> {
876    fn from_iter<I: IntoIterator<Item = &'a str>>(iter: I) -> Self {
877        let mut buf = FlexibleString::new();
878        buf.extend(iter);
879        buf
880    }
881}
882
883impl<const CAPACITY_LHS: usize, const CAPACITY_RHS: usize>
884    FromIterator<FlexibleString<CAPACITY_RHS>> for FlexibleString<CAPACITY_LHS>
885{
886    fn from_iter<I: IntoIterator<Item = FlexibleString<CAPACITY_RHS>>>(
887        iter: I,
888    ) -> FlexibleString<CAPACITY_LHS> {
889        let mut buf = FlexibleString::new();
890        buf.extend(iter);
891        buf
892    }
893}
894
895impl<const CAPACITY: usize> FromIterator<char> for FlexibleString<CAPACITY> {
896    fn from_iter<I: IntoIterator<Item = char>>(iter: I) -> Self {
897        let mut buf = FlexibleString::new();
898        buf.extend(iter);
899        buf
900    }
901}
902
903impl<const CAPACITY: usize> FromIterator<Box<str>> for FlexibleString<CAPACITY> {
904    fn from_iter<I: IntoIterator<Item = Box<str>>>(iter: I) -> Self {
905        let mut buf = FlexibleString::new();
906        buf.extend(iter);
907        buf
908    }
909}
910
911impl<const CAPACITY: usize> Extend<char> for FlexibleString<CAPACITY> {
912    fn extend<I: IntoIterator<Item = char>>(&mut self, iter: I) {
913        let iterator = iter.into_iter();
914        let (lower_bound, _) = iterator.size_hint();
915        self.reserve(lower_bound);
916        iterator.for_each(move |c| self.push(c));
917    }
918
919    // comment out these 2 functions since they are currently unstable.
920
921    // #[inline]
922    // fn extend_one(&mut self, c: char) {
923    //     self.push(c);
924    // }
925
926    // #[inline]
927    // fn extend_reserve(&mut self, additional: usize) {
928    //     self.reserve(additional);
929    // }
930}
931
932impl<'a, const CAPACITY: usize> Extend<&'a char> for FlexibleString<CAPACITY> {
933    fn extend<I: IntoIterator<Item = &'a char>>(&mut self, iter: I) {
934        self.extend(iter.into_iter().cloned());
935    }
936
937    // comment out these 2 functions since they are currently unstable.
938
939    // #[inline]
940    // fn extend_one(&mut self, &c: &'a char) {
941    //     self.push(c);
942    // }
943
944    // #[inline]
945    // fn extend_reserve(&mut self, additional: usize) {
946    //     self.reserve(additional);
947    // }
948}
949
950impl<'a, const CAPACITY: usize> Extend<&'a str> for FlexibleString<CAPACITY> {
951    fn extend<I: IntoIterator<Item = &'a str>>(&mut self, iter: I) {
952        iter.into_iter().for_each(move |s| self.push_str(s));
953    }
954
955    // comment out this function since it is currently unstable.
956
957    // #[inline]
958    // fn extend_one(&mut self, s: &'a str) {
959    //     self.push_str(s);
960    // }
961}
962
963impl<'a, const CAPACITY: usize> Extend<Box<str>> for FlexibleString<CAPACITY> {
964    fn extend<I: IntoIterator<Item = Box<str>>>(&mut self, iter: I) {
965        iter.into_iter().for_each(move |s| self.push_str(&s));
966    }
967}
968
969impl<const CAPACITY_LHS: usize, const CAPACITY_RHS: usize> Extend<FlexibleString<CAPACITY_RHS>>
970    for FlexibleString<CAPACITY_LHS>
971{
972    fn extend<I: IntoIterator<Item = FlexibleString<CAPACITY_RHS>>>(&mut self, iter: I) {
973        iter.into_iter().for_each(move |s| self.push_str(&s));
974    }
975
976    // comment out this function since it is currently unstable.
977
978    // #[inline]
979    // fn extend_one(&mut self, s: FlexibleString<CAPACITY_RHS>) {
980    //     self.push_str(&s);
981    // }
982}
983
984impl<const CAPACITY: usize> str::FromStr for FlexibleString<CAPACITY> {
985    type Err = core::convert::Infallible;
986
987    #[inline]
988    fn from_str(s: &str) -> Result<FlexibleString<CAPACITY>, Self::Err> {
989        Ok(FlexibleString::from(s))
990    }
991}
992
993impl<const CAPACITY: usize> ops::Add<&str> for FlexibleString<CAPACITY> {
994    type Output = FlexibleString<CAPACITY>;
995
996    #[inline]
997    fn add(mut self, other: &str) -> Self {
998        self.push_str(other);
999        self
1000    }
1001}
1002
1003impl<const CAPACITY: usize> ops::AddAssign<&str> for FlexibleString<CAPACITY> {
1004    #[inline]
1005    fn add_assign(&mut self, other: &str) {
1006        self.push_str(other);
1007    }
1008}
1009
1010impl<const CAPACITY: usize> ops::Deref for FlexibleString<CAPACITY> {
1011    type Target = str;
1012
1013    common_methods! {
1014        NEVER_UPGRADE => fn deref([&]self) -> &str;
1015    }
1016}
1017
1018impl<const CAPACITY: usize> ops::DerefMut for FlexibleString<CAPACITY> {
1019    common_methods! {
1020        NEVER_UPGRADE => fn deref_mut([&mut]self) -> &mut str;
1021    }
1022}
1023
1024impl<const CAPACITY: usize> fmt::Write for FlexibleString<CAPACITY> {
1025    #[inline]
1026    fn write_str(&mut self, s: &str) -> fmt::Result {
1027        self.push_str(s);
1028        Ok(())
1029    }
1030
1031    #[inline]
1032    fn write_char(&mut self, c: char) -> fmt::Result {
1033        self.push(c);
1034        Ok(())
1035    }
1036}
1037
1038impl<const CAPACITY: usize> fmt::Display for FlexibleString<CAPACITY> {
1039    #[inline]
1040    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1041        fmt::Display::fmt(&**self, f)
1042    }
1043}
1044
1045impl<const CAPACITY: usize> fmt::Debug for FlexibleString<CAPACITY> {
1046    #[inline]
1047    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1048        fmt::Debug::fmt(&**self, f)
1049    }
1050}
1051
1052#[derive(Clone)]
1053struct StackString<const CAPACITY: usize> {
1054    data: [MaybeUninit<u8>; CAPACITY],
1055    len: usize,
1056}
1057
1058// Err(EstimatedCapacity) if the stack size is not enough, we must switch to use the heap.
1059type StackStringResult<T> = Result<T, Option<usize>>;
1060
1061impl<const CAPACITY: usize> StackString<CAPACITY> {
1062    #[inline]
1063    fn new() -> Self {
1064        Self {
1065            data: unsafe { MaybeUninit::uninit().assume_init() },
1066            len: 0,
1067        }
1068    }
1069
1070    #[inline]
1071    unsafe fn from_utf8_vec_only_len_unchecked(vec: Vec<u8>) -> Result<Self, FromUtf8Error> {
1072        match str::from_utf8(&vec) {
1073            Ok(..) => Ok(Self::from_utf8_slice_unchecked(&vec)),
1074            Err(e) => Err(FromUtf8Error {
1075                bytes: vec,
1076                error: e,
1077            }),
1078        }
1079    }
1080
1081    #[inline]
1082    unsafe fn from_utf8_slice_unchecked(bytes: &[u8]) -> Self {
1083        let mut res = Self::new();
1084        res.copy_append_unchecked(bytes.as_ptr(), bytes.len());
1085        res
1086    }
1087
1088    #[inline]
1089    fn into_bytes(self) -> Vec<u8> {
1090        self.as_bytes().into()
1091    }
1092
1093    #[inline]
1094    fn as_str(&self) -> &str {
1095        self
1096    }
1097
1098    #[inline]
1099    fn as_mut_str(&mut self) -> &mut str {
1100        self
1101    }
1102
1103    #[inline]
1104    fn push_str(&mut self, string: &str) -> StackStringResult<()> {
1105        let len_needed = self.len + string.len();
1106        if len_needed > CAPACITY {
1107            Err(Some(len_needed))
1108        } else {
1109            unsafe {
1110                self.copy_append_unchecked(string.as_ptr(), string.len());
1111            }
1112            Ok(())
1113        }
1114    }
1115
1116    #[inline]
1117    const fn capacity(&self) -> usize {
1118        CAPACITY
1119    }
1120
1121    #[inline]
1122    fn reserve(&mut self, additional: usize) -> StackStringResult<()> {
1123        let cap_at_least = self.len + additional;
1124        if cap_at_least > CAPACITY {
1125            Err(Some(cap_at_least))
1126        } else {
1127            Ok(())
1128        }
1129    }
1130
1131    #[inline]
1132    fn reserve_exact(&mut self, additional: usize) -> StackStringResult<()> {
1133        self.reserve(additional)
1134    }
1135
1136    // comment out these 2 functions since `TryReserveErrorKind` is currently unstable.
1137    //
1138    // fn try_reserve(&mut self, additional: usize) -> StackStringResult<Result<(), TryReserveError>> {
1139    //     let cap_at_least = self.len + additional;
1140    //     if cap_at_least > CAPACITY {
1141    //         Err(Some(cap_at_least))
1142    //     } else {
1143    //         Ok(Ok(()))
1144    //     }
1145    // }
1146    //
1147    // fn try_reserve_exact(
1148    //     &mut self,
1149    //     additional: usize,
1150    // ) -> StackStringResult<Result<(), TryReserveError>> {
1151    //     self.try_reserve(additional)
1152    // }
1153
1154    #[inline]
1155    fn shrink_to(&mut self, _min_capacity: usize) {
1156        // just do nothing :)
1157    }
1158
1159    #[inline]
1160    fn push(&mut self, ch: char) -> StackStringResult<()> {
1161        let len_utf8 = ch.len_utf8();
1162        let len_needed = self.len + len_utf8;
1163
1164        if len_needed > CAPACITY {
1165            Err(Some(len_needed))
1166        } else {
1167            match len_utf8 {
1168                1 => {
1169                    unsafe { *self.data[self.len].as_mut_ptr() = ch as u8 }
1170                    self.len += 1;
1171                }
1172                test_len_utf8 => {
1173                    let mut buf = [0; 4];
1174                    let bytes = ch.encode_utf8(&mut buf).as_bytes();
1175                    debug_assert_eq!(test_len_utf8, bytes.len());
1176                    unsafe { self.copy_append_unchecked(bytes.as_ptr(), bytes.len()) }
1177                }
1178            }
1179            Ok(())
1180        }
1181    }
1182
1183    #[inline]
1184    fn as_bytes(&self) -> &[u8] {
1185        unsafe { slice::from_raw_parts(self.as_ptr(), self.len) }
1186    }
1187
1188    #[inline]
1189    fn as_bytes_mut(&mut self) -> &mut [u8] {
1190        unsafe { slice::from_raw_parts_mut(self.as_mut_ptr(), self.len) }
1191    }
1192
1193    #[inline]
1194    fn truncate(&mut self, new_len: usize) {
1195        if new_len <= self.len {
1196            assert!(self.is_char_boundary(new_len));
1197            unsafe {
1198                self.set_len(new_len);
1199            }
1200        }
1201    }
1202
1203    #[inline]
1204    fn pop(&mut self) -> Option<char> {
1205        let ch = self.chars().rev().next()?;
1206        let newlen = self.len() - ch.len_utf8();
1207        unsafe {
1208            self.set_len(newlen);
1209        }
1210        Some(ch)
1211    }
1212
1213    #[inline]
1214    fn remove(&mut self, idx: usize) -> char {
1215        let ch = match self[idx..].chars().next() {
1216            Some(ch) => ch,
1217            None => panic!("cannot remove a char from the end of a string"),
1218        };
1219
1220        let next = idx + ch.len_utf8();
1221        let len = self.len();
1222        unsafe {
1223            ptr::copy(
1224                self.as_ptr().add(next),
1225                self.as_mut_ptr().add(idx),
1226                len - next,
1227            );
1228            self.set_len(len - (next - idx));
1229        }
1230        ch
1231    }
1232
1233    #[inline]
1234    fn insert(&mut self, idx: usize, ch: char) -> StackStringResult<()> {
1235        assert!(self.is_char_boundary(idx));
1236        let mut bits = [0; 4];
1237        let bits = ch.encode_utf8(&mut bits).as_bytes();
1238
1239        unsafe { self.insert_bytes(idx, bits) }
1240    }
1241
1242    #[inline]
1243    fn insert_str(&mut self, idx: usize, string: &str) -> StackStringResult<()> {
1244        assert!(self.is_char_boundary(idx));
1245
1246        unsafe { self.insert_bytes(idx, string.as_bytes()) }
1247    }
1248
1249    #[inline]
1250    fn len(&self) -> usize {
1251        self.len
1252    }
1253
1254    #[inline]
1255    fn is_empty(&self) -> bool {
1256        self.len == 0
1257    }
1258
1259    #[inline]
1260    fn clear(&mut self) {
1261        self.truncate(0)
1262    }
1263
1264    #[inline]
1265    unsafe fn set_len(&mut self, new_len: usize) {
1266        debug_assert!(new_len <= CAPACITY);
1267        self.len = new_len;
1268    }
1269
1270    //////////
1271
1272    #[inline]
1273    fn as_ptr(&self) -> *const u8 {
1274        self.data.as_ptr() as *const u8
1275    }
1276
1277    #[inline]
1278    fn as_mut_ptr(&mut self) -> *mut u8 {
1279        self.data.as_mut_ptr() as *mut u8
1280    }
1281
1282    #[inline]
1283    unsafe fn copy_append_unchecked(&mut self, src: *const u8, len: usize) {
1284        let dst = self.as_mut_ptr().add(self.len);
1285        ptr::copy_nonoverlapping(src, dst, len);
1286        self.len += len;
1287    }
1288
1289    #[inline]
1290    fn to_heap(&self, estimated_capacity: Option<usize>) -> String {
1291        let bytes = self.as_bytes();
1292
1293        if let Some(capacity) = estimated_capacity {
1294            let mut vec = Vec::with_capacity(capacity);
1295            vec.extend_from_slice(bytes);
1296            unsafe { String::from_utf8_unchecked(vec) }
1297        } else {
1298            unsafe { String::from_utf8_unchecked(bytes.into()) }
1299        }
1300    }
1301
1302    #[inline]
1303    unsafe fn insert_bytes(&mut self, idx: usize, bytes: &[u8]) -> StackStringResult<()> {
1304        let len = self.len();
1305        let amt = bytes.len();
1306
1307        let len_needed = len + amt;
1308        if len_needed > CAPACITY {
1309            return Err(Some(len_needed));
1310        }
1311
1312        ptr::copy(
1313            self.as_ptr().add(idx),
1314            self.as_mut_ptr().add(idx + amt),
1315            len - idx,
1316        );
1317        ptr::copy_nonoverlapping(bytes.as_ptr(), self.as_mut_ptr().add(idx), amt);
1318        self.set_len(len_needed);
1319
1320        Ok(())
1321    }
1322}
1323
1324impl<const CAPACITY: usize> ops::Deref for StackString<CAPACITY> {
1325    type Target = str;
1326
1327    #[inline]
1328    fn deref(&self) -> &str {
1329        let bytes = self.as_bytes();
1330        unsafe { str::from_utf8_unchecked(bytes) }
1331    }
1332}
1333
1334impl<const CAPACITY: usize> ops::DerefMut for StackString<CAPACITY> {
1335    #[inline]
1336    fn deref_mut(&mut self) -> &mut str {
1337        let bytes = self.as_bytes_mut();
1338        unsafe { str::from_utf8_unchecked_mut(bytes) }
1339    }
1340}
1341
1342impl<const CAPACITY: usize> fmt::Debug for StackString<CAPACITY> {
1343    #[inline]
1344    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1345        fmt::Debug::fmt(&**self, f)
1346    }
1347}
1348
1349//////////////////////////////////////////////////
1350
1351impl FromUtf8Error {
1352    /// Returns a slice of [`u8`]s bytes that were attempted to convert to a `FlexibleString`.
1353    ///
1354    /// # Examples
1355    ///
1356    /// Basic usage:
1357    ///
1358    /// ```
1359    /// use flexible_string::FlexibleString;
1360    ///
1361    /// // some invalid bytes, in a vector
1362    /// let bytes = vec![0, 159];
1363    ///
1364    /// let value = FlexibleString::<200>::from_utf8(bytes);
1365    ///
1366    /// assert_eq!(&[0, 159], value.unwrap_err().as_bytes());
1367    /// ```
1368    #[inline]
1369    pub fn as_bytes(&self) -> &[u8] {
1370        &self.bytes[..]
1371    }
1372
1373    /// Returns the bytes that were attempted to convert to a `FlexibleString`.
1374    ///
1375    /// This method is carefully constructed to avoid allocation. It will
1376    /// consume the error, moving out the bytes, so that a copy of the bytes
1377    /// does not need to be made.
1378    ///
1379    /// # Examples
1380    ///
1381    /// Basic usage:
1382    ///
1383    /// ```
1384    /// use flexible_string::FlexibleString;
1385    ///
1386    /// // some invalid bytes, in a vector
1387    /// let bytes = vec![0, 159];
1388    ///
1389    /// let value = FlexibleString::<200>::from_utf8(bytes);
1390    ///
1391    /// assert_eq!(vec![0, 159], value.unwrap_err().into_bytes());
1392    /// ```
1393    #[inline]
1394    pub fn into_bytes(self) -> Vec<u8> {
1395        self.bytes
1396    }
1397
1398    /// Fetch a `Utf8Error` to get more details about the conversion failure.
1399    ///
1400    /// The [`std::str::Utf8Error`] type represents an error that may
1401    /// occur when converting a slice of [`u8`]s to a [`&str`]. In this sense, it's
1402    /// an analogue to `FromUtf8Error`. See its documentation for more details
1403    /// on using it.
1404    ///
1405    /// [`std::str`]: core::str "std::str"
1406    /// [`&str`]: prim@str "&str"
1407    ///
1408    /// # Examples
1409    ///
1410    /// Basic usage:
1411    ///
1412    /// ```
1413    /// use flexible_string::FlexibleString;
1414    ///
1415    /// // some invalid bytes, in a vector
1416    /// let bytes = vec![0, 159];
1417    ///
1418    /// let error = FlexibleString::<200>::from_utf8(bytes).unwrap_err().utf8_error();
1419    ///
1420    /// // the first byte is invalid here
1421    /// assert_eq!(1, error.valid_up_to());
1422    /// ```
1423    #[inline]
1424    pub fn utf8_error(&self) -> str::Utf8Error {
1425        self.error
1426    }
1427}
1428
1429impl From<string::FromUtf8Error> for FromUtf8Error {
1430    fn from(std_err: string::FromUtf8Error) -> Self {
1431        let err = std_err.utf8_error();
1432        Self {
1433            bytes: std_err.into_bytes(),
1434            error: err,
1435        }
1436    }
1437}
1438
1439impl fmt::Display for FromUtf8Error {
1440    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1441        fmt::Display::fmt(&self.error, f)
1442    }
1443}
1444
1445#[cfg(test)]
1446mod tests {
1447    use super::*;
1448
1449    #[test]
1450    fn heterogeneous_cmp() {
1451        assert_eq!(
1452            FlexibleString::<100>::from("hello"),
1453            FlexibleString::<200>::from("hello")
1454        );
1455
1456        assert_eq!(FlexibleString::<100>::from("hello"), "hello");
1457        assert_eq!("hello", FlexibleString::<100>::from("hello"));
1458
1459        assert_eq!(FlexibleString::<100>::from("hello"), String::from("hello"));
1460        assert_eq!(String::from("hello"), FlexibleString::<100>::from("hello"));
1461    }
1462}