Skip to content

Commit

Permalink
Fix remainder (#27)
Browse files Browse the repository at this point in the history
  • Loading branch information
GeorgeLyon authored Mar 29, 2024
1 parent f73c481 commit d7be048
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 19 deletions.
32 changes: 20 additions & 12 deletions Sources/Shwift/Builtins.swift
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ extension Builtin {
}

fileprivate init(byteBuffers: ByteBuffers) {
segments = Segments(byteBuffers: byteBuffers, delimiter: "\n")
segments = Segments(byteBuffers: byteBuffers, separator: "\n")
}
private let segments: Segments
}
Expand All @@ -124,13 +124,13 @@ extension Builtin {
at: buffer.readerIndex,
length: buffer.readableBytes)!
var substring = readString[readString.startIndex...]
while let lineBreak = substring.firstIndex(of: delimiter) {
let line = substring[substring.startIndex..<lineBreak]
substring = substring[substring.index(after: lineBreak)...]
continuation.yield(remainder + String(line))
while let separatorRange = substring.range(of: separator) {
let segment = substring[substring.startIndex..<separatorRange.lowerBound]
substring = substring[separatorRange.upperBound...]
continuation.yield(remainder + String(segment))
remainder = ""
}
remainder = String(substring)
remainder += String(substring)
}
if !remainder.isEmpty {
continuation.yield(String(remainder))
Expand All @@ -145,22 +145,30 @@ extension Builtin {
}

fileprivate let byteBuffers: ByteBuffers
fileprivate let delimiter: Character
fileprivate let separator: String
}

/// Make a Lines iterator splitting at newlines
public var lines: Lines {
Lines(byteBuffers: byteBuffers)
}

/// Make a Lines iterator yielding text segments between delimiters (like split).
/// Segment this input using a separator.
///
/// - Parameter delimiter: Character separating input text to yield (and not itself yielded) Defaults to newline.
/// - Returns: Lines segmented by delimiter
public func segments(separatedBy delimiter: Character) -> Segments {
Segments(byteBuffers: byteBuffers, delimiter: delimiter)
/// - Parameter delimiter: Character separating segments of the input
/// - Returns: Segments segmented by the separator
public func segments(separatedBy separator: Character) -> Segments {
segments(separatedBy: "\(separator)")
}

/// Segment this input using a separator.
///
/// - Parameters:
/// - separator: String separating segments of the input. Must not be empty
/// - Returns: Segments segmented by the separator
public func segments(separatedBy separator: String) -> Segments {
Segments(byteBuffers: byteBuffers, separator: separator)
}
typealias ByteBuffers = AsyncCompactMapSequence<
AsyncPrefixWhileSequence<AsyncInboundHandler<ByteBuffer>>, ByteBuffer
>
Expand Down
14 changes: 7 additions & 7 deletions Tests/ShwiftTests/Shwift Tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,22 +65,22 @@ final class ShwiftCoreTests: XCTestCase {
of: { context, output in
try await Builtin.pipe(
{ output in
try await Process.run("echo", "Foo;Bar;Baz", standardOutput: output, in: context)
try await Process.run("echo", "-n", "Foo;-Bar;Baz", standardOutput: output, in: context)
},
to: { input in
try await Builtin.withChannel(input: input, output: output, in: context) { channel in
let count = try await channel.input
.segments(separatedBy: ";")
.reduce(into: 0, { count, _ in count += 1 })
try await channel.output.withTextOutputStream { stream in
print("\(count)", to: &stream)
for try await segment in channel.input.segments(separatedBy: ";-") {
try await channel.output.withTextOutputStream { stream in
print(segment, to: &stream)
}
}
}
}
).destination
},
is: """
3
Foo
Bar;Baz
""")
}

Expand Down

0 comments on commit d7be048

Please sign in to comment.