1
1
// Take a look at the license at the top of the repository in the LICENSE file.
2
2
3
3
use crate :: translate:: * ;
4
+ use crate :: GStr ;
4
5
use std:: cmp;
5
6
use std:: fmt;
6
7
use std:: hash;
@@ -15,11 +16,17 @@ wrapper! {
15
16
/// A mutable text buffer that grows automatically.
16
17
#[ doc( alias = "GString" ) ]
17
18
#[ must_use = "The builder must be built to be used" ]
18
- pub struct GStringBuilder ( Boxed <ffi:: GString >) ;
19
+ pub struct GStringBuilder ( BoxedInline <ffi:: GString >) ;
19
20
20
21
match fn {
21
- copy => |ptr| ffi:: g_string_new ( ( * ptr) . str ) ,
22
+ copy => |ptr| ffi:: g_string_new_len ( ( * ptr) . str , ( * ptr ) . len . try_into ( ) . unwrap ( ) ) ,
22
23
free => |ptr| ffi:: g_string_free( ptr, ffi:: GTRUE ) ,
24
+ init => |ptr| ptr:: write( ptr, mem:: zeroed( ) ) ,
25
+ copy_into => |dest, src| {
26
+ ptr:: write( dest, mem:: zeroed( ) ) ;
27
+ ffi:: g_string_append_len( dest, ( * src) . str , ( * src) . len. try_into( ) . unwrap( ) ) ;
28
+ } ,
29
+ clear => |ptr| ffi:: g_free( ( * ptr) . str as * mut _) ,
23
30
type_ => || ffi:: g_gstring_get_type( ) ,
24
31
}
25
32
}
@@ -80,7 +87,7 @@ impl GStringBuilder {
80
87
}
81
88
82
89
// rustdoc-stripper-ignore-next
83
- /// Returns `& str` slice.
90
+ /// Returns <code>&[ str]</code> slice.
84
91
///
85
92
/// # Panics
86
93
///
@@ -98,28 +105,48 @@ impl GStringBuilder {
98
105
}
99
106
100
107
// rustdoc-stripper-ignore-next
101
- /// Returns `&str` slice.
108
+ /// Returns <code>&[GStr]</code> slice.
102
109
///
103
110
/// # Panics
104
111
///
105
112
/// If the string builder contains invalid UTF-8 this function panics.
106
- #[ must_use = "String returned from the builder should probably be used" ]
107
- pub fn into_string ( self ) -> crate :: GString {
113
+ pub fn as_gstr ( & self ) -> & GStr {
108
114
unsafe {
109
- let s = mem:: ManuallyDrop :: new ( self ) ;
110
- from_glib_full ( ffi:: g_string_free (
111
- mut_override ( s. to_glib_none ( ) . 0 ) ,
112
- ffi:: GFALSE ,
113
- ) )
115
+ let ptr: * const u8 = self . inner . str as _ ;
116
+ let len: usize = self . inner . len ;
117
+ if len == 0 {
118
+ return Default :: default ( ) ;
119
+ }
120
+ let slice = slice:: from_raw_parts ( ptr, len + 1 ) ;
121
+ GStr :: from_utf8_with_nul_checked ( slice) . unwrap ( )
114
122
}
115
123
}
124
+
125
+ // rustdoc-stripper-ignore-next
126
+ /// FInalizes the builder, converting it to a [`GString`].
127
+ ///
128
+ /// # Panics
129
+ ///
130
+ /// If the string builder contains invalid UTF-8 this function panics.
131
+ #[ must_use = "String returned from the builder should probably be used" ]
132
+ pub fn into_string ( self ) -> crate :: GString {
133
+ let s = mem:: ManuallyDrop :: new ( self ) ;
134
+ let len = s. len ( ) ;
135
+ unsafe { FromGlibContainer :: from_glib_full_num ( s. inner . str , len) }
136
+ }
116
137
}
117
138
118
139
impl Default for GStringBuilder {
119
140
// rustdoc-stripper-ignore-next
120
141
/// Creates a new empty string.
121
142
fn default ( ) -> Self {
122
- unsafe { from_glib_full ( ffi:: g_string_new ( ptr:: null ( ) ) ) }
143
+ Self {
144
+ inner : ffi:: GString {
145
+ str : ptr:: null_mut ( ) ,
146
+ len : 0 ,
147
+ allocated_len : 0 ,
148
+ } ,
149
+ }
123
150
}
124
151
}
125
152
@@ -153,6 +180,18 @@ impl PartialEq<GStringBuilder> for str {
153
180
}
154
181
}
155
182
183
+ impl PartialEq < GStr > for GStringBuilder {
184
+ fn eq ( & self , other : & GStr ) -> bool {
185
+ self . as_gstr ( ) == other
186
+ }
187
+ }
188
+
189
+ impl PartialEq < GStringBuilder > for GStr {
190
+ fn eq ( & self , other : & GStringBuilder ) -> bool {
191
+ self == other. as_gstr ( )
192
+ }
193
+ }
194
+
156
195
impl Eq for GStringBuilder { }
157
196
158
197
impl cmp:: PartialOrd for GStringBuilder {
@@ -173,6 +212,18 @@ impl cmp::PartialOrd<GStringBuilder> for str {
173
212
}
174
213
}
175
214
215
+ impl cmp:: PartialOrd < GStr > for GStringBuilder {
216
+ fn partial_cmp ( & self , other : & GStr ) -> Option < cmp:: Ordering > {
217
+ Some ( self . as_gstr ( ) . cmp ( other) )
218
+ }
219
+ }
220
+
221
+ impl cmp:: PartialOrd < GStringBuilder > for GStr {
222
+ fn partial_cmp ( & self , other : & GStringBuilder ) -> Option < cmp:: Ordering > {
223
+ Some ( self . cmp ( other. as_gstr ( ) ) )
224
+ }
225
+ }
226
+
176
227
impl cmp:: Ord for GStringBuilder {
177
228
fn cmp ( & self , other : & Self ) -> cmp:: Ordering {
178
229
self . as_str ( ) . cmp ( other. as_str ( ) )
@@ -200,6 +251,12 @@ impl AsRef<str> for GStringBuilder {
200
251
}
201
252
}
202
253
254
+ impl AsRef < GStr > for GStringBuilder {
255
+ fn as_ref ( & self ) -> & GStr {
256
+ self . as_gstr ( )
257
+ }
258
+ }
259
+
203
260
impl ops:: Deref for GStringBuilder {
204
261
type Target = str ;
205
262
0 commit comments