> 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

Reply via email to