@@ -8,7 +8,8 @@ use crate::{pg_sys, varlena};
88use alloc:: borrow:: Cow ;
99use alloc:: string:: String ;
1010use core:: borrow:: Borrow ;
11- use core:: { ptr, slice, str} ;
11+ use core:: ops:: { Deref , DerefMut } ;
12+ use core:: { ptr, str} ;
1213
1314use bstr:: { BStr , ByteSlice } ;
1415
@@ -24,44 +25,33 @@ pub use core::str::{Utf8Chunks, Utf8Error};
2425#[ repr( transparent) ]
2526pub struct Text ( [ u8 ] ) ;
2627
27- // API decision: we could deref to TextData and move some fn to TextData so it can be returned from
28- // `split_at`, `trim`, etc., and thus preserve conveniences that [u8] doesn't have?
28+ /// Data field of a TEXT varlena
29+ #[ repr( transparent) ]
30+ pub struct TextData ( [ u8 ] ) ;
31+
32+ impl TextData {
33+ /// Reborrow `&Text as `&BStr`
34+ ///
35+ /// We do not implement Deref to BStr or [u8] because we'd like to expose a more selective API.
36+ /// Several fn that [u8] implements are implemented very differently on str, and we would like
37+ /// the API of Text to "feel like" that of str in most cases.
38+ fn as_bstr ( & self ) -> & BStr {
39+ self . as_bytes ( ) . borrow ( )
40+ }
2941
30- impl Text {
3142 /// Obtain a reference to the Text's data as bytes
3243 pub fn as_bytes ( & self ) -> & [ u8 ] {
33- let self_ptr = self as * const Text as * const pg_sys:: varlena ;
34- unsafe {
35- let len = varlena:: varsize_any_exhdr ( self_ptr) ;
36- let data = varlena:: vardata_any ( self_ptr) ;
37-
38- slice:: from_raw_parts ( data. cast :: < u8 > ( ) , len)
39- }
44+ & self . 0
4045 }
4146
42- /// Obtain a mutable reference the Text's data as bytes
47+ /// Obtain a mutable reference to the Text's data as bytes
4348 ///
4449 /// # Safety
4550 /// Like [`str::as_bytes_mut`], this can cause problems if you change Text in a way that
4651 /// your database is not specified to support, so the caller must assure that it remains in
4752 /// a valid encoding for the database.
4853 pub unsafe fn as_bytes_mut ( & mut self ) -> & mut [ u8 ] {
49- let self_ptr = self as * mut Text as * mut pg_sys:: varlena ;
50- unsafe {
51- let len = varlena:: varsize_any_exhdr ( self_ptr) ;
52- let data = varlena:: vardata_any ( self_ptr) ;
53-
54- slice:: from_raw_parts_mut ( data. cast :: < u8 > ( ) . cast_mut ( ) , len)
55- }
56- }
57-
58- /// Reborrow `&Text as `&BStr`
59- ///
60- /// We do not implement Deref to BStr or [u8] because we'd like to expose a more selective API.
61- /// Several fn that [u8] implements are implemented very differently on str, and we would like
62- /// the API of Text to "feel like" that of str in most cases.
63- fn as_bstr ( & self ) -> & BStr {
64- self . as_bytes ( ) . borrow ( )
54+ & mut self . 0
6555 }
6656
6757 /// Iterate over the UTF-8 characters of this Text
@@ -81,22 +71,17 @@ impl Text {
8171 self . as_bytes ( ) . is_ascii ( )
8272 }
8373
84- /// Is the varlena larger than its header ?
74+ /// Is this slice nonzero len ?
8575 pub fn is_empty ( & self ) -> bool {
8676 self . as_bytes ( ) . is_empty ( )
8777 }
8878
8979 /// Length of the data in bytes
90- pub fn len_data ( & self ) -> usize {
80+ pub fn len ( & self ) -> usize {
9181 self . as_bytes ( ) . len ( )
9282 }
9383
94- /// Length of the entire varlena in bytes
95- pub fn len_full ( & self ) -> usize {
96- self . 0 . len ( )
97- }
98-
99- /// Obtain a reference to the varlena data if it is a UTF-8 str
84+ /// Obtain a reference to the data if it is a UTF-8 str
10085 pub fn to_str ( & self ) -> Result < & str , Utf8Error > {
10186 str:: from_utf8 ( self . as_bytes ( ) )
10287 }
@@ -114,6 +99,34 @@ impl Text {
11499 }
115100}
116101
102+ impl Text {
103+ /// Length of the entire varlena in bytes
104+ pub fn va_len ( & self ) -> usize {
105+ self . 0 . len ( )
106+ }
107+ }
108+
109+ impl Deref for Text {
110+ type Target = TextData ;
111+ fn deref ( & self ) -> & Self :: Target {
112+ let self_ptr = self as * const Text as * const pg_sys:: varlena ;
113+ unsafe { & * varlena_to_text_data ( self_ptr. cast_mut ( ) ) }
114+ }
115+ }
116+
117+ impl DerefMut for Text {
118+ fn deref_mut ( & mut self ) -> & mut Self :: Target {
119+ let self_ptr = self as * mut Text as * mut pg_sys:: varlena ;
120+ unsafe { & mut * varlena_to_text_data ( self_ptr) }
121+ }
122+ }
123+
124+ unsafe fn varlena_to_text_data ( vptr : * mut pg_sys:: varlena ) -> * mut TextData {
125+ let len = varlena:: varsize_any_exhdr ( vptr) ;
126+ let data = varlena:: vardata_any ( vptr) . cast_mut ( ) ;
127+ ptr:: slice_from_raw_parts_mut ( data. cast :: < u8 > ( ) , len) as * mut TextData
128+ }
129+
117130unsafe impl BorrowDatum for Text {
118131 const PASS : PassBy = PassBy :: Ref ;
119132 unsafe fn point_from ( ptr : ptr:: NonNull < u8 > ) -> ptr:: NonNull < Self > {
0 commit comments