@@ -8,7 +8,8 @@ use crate::{pg_sys, varlena};
8
8
use alloc:: borrow:: Cow ;
9
9
use alloc:: string:: String ;
10
10
use core:: borrow:: Borrow ;
11
- use core:: { ptr, slice, str} ;
11
+ use core:: ops:: { Deref , DerefMut } ;
12
+ use core:: { ptr, str} ;
12
13
13
14
use bstr:: { BStr , ByteSlice } ;
14
15
@@ -24,44 +25,33 @@ pub use core::str::{Utf8Chunks, Utf8Error};
24
25
#[ repr( transparent) ]
25
26
pub struct Text ( [ u8 ] ) ;
26
27
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
+ }
29
41
30
- impl Text {
31
42
/// Obtain a reference to the Text's data as bytes
32
43
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
40
45
}
41
46
42
- /// Obtain a mutable reference the Text's data as bytes
47
+ /// Obtain a mutable reference to the Text's data as bytes
43
48
///
44
49
/// # Safety
45
50
/// Like [`str::as_bytes_mut`], this can cause problems if you change Text in a way that
46
51
/// your database is not specified to support, so the caller must assure that it remains in
47
52
/// a valid encoding for the database.
48
53
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
65
55
}
66
56
67
57
/// Iterate over the UTF-8 characters of this Text
@@ -81,22 +71,17 @@ impl Text {
81
71
self . as_bytes ( ) . is_ascii ( )
82
72
}
83
73
84
- /// Is the varlena larger than its header ?
74
+ /// Is this slice nonzero len ?
85
75
pub fn is_empty ( & self ) -> bool {
86
76
self . as_bytes ( ) . is_empty ( )
87
77
}
88
78
89
79
/// Length of the data in bytes
90
- pub fn len_data ( & self ) -> usize {
80
+ pub fn len ( & self ) -> usize {
91
81
self . as_bytes ( ) . len ( )
92
82
}
93
83
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
100
85
pub fn to_str ( & self ) -> Result < & str , Utf8Error > {
101
86
str:: from_utf8 ( self . as_bytes ( ) )
102
87
}
@@ -114,6 +99,37 @@ impl Text {
114
99
}
115
100
}
116
101
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
+ unsafe {
126
+ let len = varlena:: varsize_any_exhdr ( vptr) ;
127
+ let data = varlena:: vardata_any ( vptr) . cast_mut ( ) ;
128
+
129
+ ptr:: slice_from_raw_parts_mut ( data. cast :: < u8 > ( ) , len) as * mut TextData
130
+ }
131
+ }
132
+
117
133
unsafe impl BorrowDatum for Text {
118
134
const PASS : PassBy = PassBy :: Ref ;
119
135
unsafe fn point_from ( ptr : ptr:: NonNull < u8 > ) -> ptr:: NonNull < Self > {
0 commit comments