@@ -359,15 +359,16 @@ pub const String = struct {
359359
360360 /// Splits the String into slices, based on a delimiter.
361361 pub fn splitAll (self : * const String , delimiters : []const u8 ) ! [][]const u8 {
362- var splitArr = std .ArrayList ([]const u8 ).init (std .heap .page_allocator );
363- defer splitArr .deinit ();
362+ const allocator = std .heap .page_allocator ;
363+ var splitArr : std .ArrayList ([]const u8 ) = .empty ;
364+ errdefer splitArr .deinit (allocator );
364365
365366 var i : usize = 0 ;
366367 while (self .split (delimiters , i )) | slice | : (i += 1 ) {
367- try splitArr .append (slice );
368+ try splitArr .append (allocator , slice );
368369 }
369370
370- return try splitArr .toOwnedSlice ();
371+ return try splitArr .toOwnedSlice (allocator );
371372 }
372373
373374 /// Splits the String into a new string, based on delimiters and an index
@@ -385,22 +386,20 @@ pub const String = struct {
385386 /// Splits the String into a slice of new Strings, based on delimiters.
386387 /// The user of this function is in charge of the memory of the new Strings.
387388 pub fn splitAllToStrings (self : * const String , delimiters : []const u8 ) ! []String {
388- var splitArr = std .ArrayList (String ).init (std .heap .page_allocator );
389- defer splitArr .deinit ();
389+ const allocator = std .heap .page_allocator ;
390+ var splitArr : std .ArrayList (String ) = .empty ;
391+ errdefer splitArr .deinit (allocator );
390392
391393 var i : usize = 0 ;
392394 while (try self .splitToString (delimiters , i )) | splitStr | : (i += 1 ) {
393- try splitArr .append (splitStr );
395+ try splitArr .append (allocator , splitStr );
394396 }
395397
396- return try splitArr .toOwnedSlice ();
398+ return try splitArr .toOwnedSlice (allocator );
397399 }
398400
399401 /// Splits the String into a slice of Strings by new line (\r\n or \n).
400402 pub fn lines (self : * String ) ! []String {
401- var lineArr = std .ArrayList (String ).init (std .heap .page_allocator );
402- defer lineArr .deinit ();
403-
404403 var selfClone = try self .clone ();
405404 defer selfClone .deinit ();
406405
@@ -486,45 +485,66 @@ pub const String = struct {
486485 }
487486
488487 // Writer functionality for the String.
489- pub usingnamespace struct {
490- pub const Writer = std .io .Writer (* String , Error , appendWrite );
491-
492- pub fn writer (self : * String ) Writer {
493- return .{ .context = self };
494- }
495-
496- fn appendWrite (self : * String , m : []const u8 ) ! usize {
497- try self .concat (m );
498- return m .len ;
488+ // pub const Writer = std.io.Writer(*String, Error, appendWrite);
489+ pub const Writer = struct {
490+ string : * String ,
491+ interface : std.Io.Writer ,
492+ err : ? Error = null ,
493+
494+ fn drain (w : * std.Io.Writer , data : []const []const u8 , splat : usize ) std.Io.Writer.Error ! usize {
495+ _ = splat ;
496+ const a : * @This () = @alignCast (@fieldParentPtr ("interface" , w ));
497+ const buffered = w .buffered ();
498+ if (buffered .len != 0 ) return w .consume (a .string .appendWrite (buffered ) catch | err | {
499+ a .err = err ;
500+ return error .WriteFailed ;
501+ });
502+ return a .string .appendWrite (data [0 ]) catch | err | {
503+ a .err = err ;
504+ return error .WriteFailed ;
505+ };
499506 }
500507 };
501508
502- // Iterator support
503- pub usingnamespace struct {
504- pub const StringIterator = struct {
505- string : * const String ,
506- index : usize ,
507-
508- pub fn next (it : * StringIterator ) ? []const u8 {
509- if (it .string .buffer ) | buffer | {
510- if (it .index == it .string .size ) return null ;
511- const i = it .index ;
512- it .index += String .getUTF8Size (buffer [i ]);
513- return buffer [i .. it .index ];
514- } else {
515- return null ;
516- }
517- }
509+ pub fn writer (self : * String , buffer : []u8 ) Writer {
510+ return .{
511+ .string = self ,
512+ .interface = .{
513+ .buffer = buffer ,
514+ .vtable = &.{ .drain = Writer .drain },
515+ },
518516 };
517+ }
519518
520- pub fn iterator (self : * const String ) StringIterator {
521- return StringIterator {
522- .string = self ,
523- .index = 0 ,
524- };
519+ fn appendWrite (self : * String , m : []const u8 ) ! usize {
520+ try self .concat (m );
521+ return m .len ;
522+ }
523+
524+ // Iterator support
525+ pub const StringIterator = struct {
526+ string : * const String ,
527+ index : usize ,
528+
529+ pub fn next (it : * StringIterator ) ? []const u8 {
530+ if (it .string .buffer ) | buffer | {
531+ if (it .index == it .string .size ) return null ;
532+ const i = it .index ;
533+ it .index += String .getUTF8Size (buffer [i ]);
534+ return buffer [i .. it .index ];
535+ } else {
536+ return null ;
537+ }
525538 }
526539 };
527540
541+ pub fn iterator (self : * const String ) StringIterator {
542+ return StringIterator {
543+ .string = self ,
544+ .index = 0 ,
545+ };
546+ }
547+
528548 /// Returns whether or not a character is whitelisted
529549 fn inWhitelist (char : u8 , whitelist : []const u8 ) bool {
530550 var i : usize = 0 ;
@@ -609,7 +629,6 @@ pub const String = struct {
609629
610630 /// Checks if the needle String is within the source String
611631 pub fn includesString (self : * String , needle : String ) bool {
612-
613632 if (self .size == 0 or needle .size == 0 ) return false ;
614633
615634 if (self .buffer ) | buffer | {
@@ -627,7 +646,6 @@ pub const String = struct {
627646
628647 /// Checks if the needle literal is within the source String
629648 pub fn includesLiteral (self : * String , needle : []const u8 ) bool {
630-
631649 if (self .size == 0 or needle .len == 0 ) return false ;
632650
633651 if (self .buffer ) | buffer | {
0 commit comments