> Looks good, but you'll want some error handling. There's no clean way to > integrate it with Generator because the protocol doesn't allow the > implementation to throw, unfortunately. (I've run into the same problem > building a Generator around a database query.) I think the best solution is > to add a property that returns the NSStream.streamError, or a checkError() > method that throws the current error if any, and have the caller use those at > the end of the iteration.
You can do better. extension NSInputStream { // I will assume you already have a byteGenerator method (which you can use with a for loop) // with a checkError() method (which throws if the generation terminated due to an error). However, // you've made these private, and will use them to implement this safe public API. public func withByteGenerator<R>(blockSize: Int = 1024, iterate: @noescape (NSInputStream.ByteGenerator) throws -> R) throws -> R { let generator = byteGenerator(blockSize: blockSize) let result = iterate(generator) try generator.checkError() return result } } Now you write: guard let stream = NSInputStream(fileAtPath: path) else { … } try stream.withByteGenerator { // XXX This would all be more complicated if CharacterGenerator can throw, too. for (i, line) in LineGenerator(source: CharacterGenerator(source: $0, decoder: UTF8())).enumerate() { print("\(i+1): \(line)") } } (I'm assuming that these generators take their almost-automatic Sequence conformance, of course.) -- Brent Royal-Gordon Architechies _______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users