@@ -9,7 +9,11 @@ use core::{
99 str:: { self , Utf8Error } ,
1010} ;
1111
12- use crate :: Vec ;
12+ use crate :: {
13+ storage:: { OwnedStorage , Storage , ViewStorage } ,
14+ vec:: VecInner ,
15+ Vec ,
16+ } ;
1317
1418/// A possible error value when converting a [`String`] from a UTF-16 byte slice.
1519///
@@ -33,11 +37,20 @@ impl fmt::Display for FromUtf16Error {
3337 }
3438}
3539
36- /// A fixed capacity [`String`](https://doc.rust-lang.org/std/string/struct.String.html).
37- pub struct String < const N : usize > {
38- vec : Vec < u8 , N > ,
40+ /// Base struct for [`String`] and [`StringView`], generic over the [`Storage`].
41+ ///
42+ /// In most cases you should use [`String`] or [`StringView`] directly. Only use this
43+ /// struct if you want to write code that's generic over both.
44+ pub struct StringInner < S : Storage > {
45+ vec : VecInner < u8 , S > ,
3946}
4047
48+ /// A fixed capacity [`String`](https://doc.rust-lang.org/std/string/struct.String.html).
49+ pub type String < const N : usize > = StringInner < OwnedStorage < N > > ;
50+
51+ /// A dynamic capacity [`String`](https://doc.rust-lang.org/std/string/struct.String.html).
52+ pub type StringView = StringInner < ViewStorage > ;
53+
4154impl < const N : usize > String < N > {
4255 /// Constructs a new, empty `String` with a fixed capacity of `N` bytes.
4356 ///
@@ -180,7 +193,9 @@ impl<const N: usize> String<N> {
180193 pub fn into_bytes ( self ) -> Vec < u8 , N > {
181194 self . vec
182195 }
196+ }
183197
198+ impl < S : Storage > StringInner < S > {
184199 /// Extracts a string slice containing the entire string.
185200 ///
186201 /// # Examples
@@ -248,7 +263,7 @@ impl<const N: usize> String<N> {
248263 /// assert_eq!(s, "olleh");
249264 /// # Ok::<(), ()>(())
250265 /// ```
251- pub unsafe fn as_mut_vec ( & mut self ) -> & mut Vec < u8 , N > {
266+ pub unsafe fn as_mut_vec ( & mut self ) -> & mut VecInner < u8 , S > {
252267 & mut self . vec
253268 }
254269
@@ -521,26 +536,26 @@ impl<const N: usize> Clone for String<N> {
521536 }
522537}
523538
524- impl < const N : usize > fmt:: Debug for String < N > {
539+ impl < S : Storage > fmt:: Debug for StringInner < S > {
525540 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
526541 <str as fmt:: Debug >:: fmt ( self , f)
527542 }
528543}
529544
530- impl < const N : usize > fmt:: Display for String < N > {
545+ impl < S : Storage > fmt:: Display for StringInner < S > {
531546 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
532547 <str as fmt:: Display >:: fmt ( self , f)
533548 }
534549}
535550
536- impl < const N : usize > hash:: Hash for String < N > {
551+ impl < S : Storage > hash:: Hash for StringInner < S > {
537552 #[ inline]
538553 fn hash < H : hash:: Hasher > ( & self , hasher : & mut H ) {
539554 <str as hash:: Hash >:: hash ( self , hasher)
540555 }
541556}
542557
543- impl < const N : usize > fmt:: Write for String < N > {
558+ impl < S : Storage > fmt:: Write for StringInner < S > {
544559 fn write_str ( & mut self , s : & str ) -> Result < ( ) , fmt:: Error > {
545560 self . push_str ( s) . map_err ( |_| fmt:: Error )
546561 }
@@ -550,82 +565,82 @@ impl<const N: usize> fmt::Write for String<N> {
550565 }
551566}
552567
553- impl < const N : usize > ops:: Deref for String < N > {
568+ impl < S : Storage > ops:: Deref for StringInner < S > {
554569 type Target = str ;
555570
556571 fn deref ( & self ) -> & str {
557572 self . as_str ( )
558573 }
559574}
560575
561- impl < const N : usize > ops:: DerefMut for String < N > {
576+ impl < S : Storage > ops:: DerefMut for StringInner < S > {
562577 fn deref_mut ( & mut self ) -> & mut str {
563578 self . as_mut_str ( )
564579 }
565580}
566581
567- impl < const N : usize > AsRef < str > for String < N > {
582+ impl < S : Storage > AsRef < str > for StringInner < S > {
568583 #[ inline]
569584 fn as_ref ( & self ) -> & str {
570585 self
571586 }
572587}
573588
574- impl < const N : usize > AsRef < [ u8 ] > for String < N > {
589+ impl < S : Storage > AsRef < [ u8 ] > for StringInner < S > {
575590 #[ inline]
576591 fn as_ref ( & self ) -> & [ u8 ] {
577592 self . as_bytes ( )
578593 }
579594}
580595
581- impl < const N1 : usize , const N2 : usize > PartialEq < String < N2 > > for String < N1 > {
582- fn eq ( & self , rhs : & String < N2 > ) -> bool {
596+ impl < S1 : Storage , S2 : Storage > PartialEq < StringInner < S1 > > for StringInner < S2 > {
597+ fn eq ( & self , rhs : & StringInner < S1 > ) -> bool {
583598 str:: eq ( & * * self , & * * rhs)
584599 }
585600}
586601
587602// String<N> == str
588- impl < const N : usize > PartialEq < str > for String < N > {
603+ impl < S : Storage > PartialEq < str > for StringInner < S > {
589604 #[ inline]
590605 fn eq ( & self , other : & str ) -> bool {
591606 str:: eq ( self , other)
592607 }
593608}
594609
595610// String<N> == &'str
596- impl < const N : usize > PartialEq < & str > for String < N > {
611+ impl < S : Storage > PartialEq < & str > for StringInner < S > {
597612 #[ inline]
598613 fn eq ( & self , other : & & str ) -> bool {
599614 str:: eq ( self , & other[ ..] )
600615 }
601616}
602617
603618// str == String<N>
604- impl < const N : usize > PartialEq < String < N > > for str {
619+ impl < S : Storage > PartialEq < StringInner < S > > for str {
605620 #[ inline]
606- fn eq ( & self , other : & String < N > ) -> bool {
621+ fn eq ( & self , other : & StringInner < S > ) -> bool {
607622 str:: eq ( self , & other[ ..] )
608623 }
609624}
610625
611626// &'str == String<N>
612- impl < const N : usize > PartialEq < String < N > > for & str {
627+ impl < S : Storage > PartialEq < StringInner < S > > for & str {
613628 #[ inline]
614- fn eq ( & self , other : & String < N > ) -> bool {
629+ fn eq ( & self , other : & StringInner < S > ) -> bool {
615630 str:: eq ( self , & other[ ..] )
616631 }
617632}
618633
619- impl < const N : usize > Eq for String < N > { }
634+ impl < S : Storage > Eq for StringInner < S > { }
620635
621- impl < const N1 : usize , const N2 : usize > PartialOrd < String < N2 > > for String < N1 > {
636+ impl < S1 : Storage , S2 : Storage > PartialOrd < StringInner < S1 > > for StringInner < S2 > {
622637 #[ inline]
623- fn partial_cmp ( & self , other : & String < N2 > ) -> Option < Ordering > {
638+ fn partial_cmp ( & self , other : & StringInner < S1 > ) -> Option < Ordering > {
624639 PartialOrd :: partial_cmp ( & * * self , & * * other)
625640 }
626641}
627642
628- impl < const N : usize > Ord for String < N > {
643+ impl < S : Storage > Ord for StringInner < S > {
629644 #[ inline]
630645 fn cmp ( & self , other : & Self ) -> Ordering {
631646 Ord :: cmp ( & * * self , & * * other)
0 commit comments