Fenrir
Fenrir copied to clipboard
Change command signatures to avoid passing output stream
Initially, most of our command code had simple signatures like this:
let packObject (input: Stream) (output: Stream): unit
It is good because it is very simple to call it from an entry point: whether we're attached to process' stdin/stdout, or take input from some files, or maybe from some memory streams – we just calculate the input/output streams, and the rest of the system is entirely isolated from these decisions.
Why have I taken this approach? Because other simple idea was to use byte lists/arrays everywhere, and it would create a huge memory impact on our code.
This approach comes with some problems though: our code is now full of stuff like this: https://github.com/ForNeVeR/Fenrir/blob/f091f85b8b09cb1813cfbeb8bcbdf2870e46ad36/Fenrir/Commands.fs#L139-L143
Currently I think it could be better and more functional to take a Stream as an input, but return a byte sequence as a result. Entry point code then will need to write the bytes to an output stream (whatever it is).
It should simplify tests and the main code (because we could use regular sequence operations without messing around with imperfect streams API), and shouldn't increase the memory impact.
Even better: return AsyncSeq<byte[]>.