Supporting Foundation.Data Without Depending On It

While implementing some file I/O APIs in Pathos, I decided reading/writing file content as Foundation.Data is kind of important (can you blame me?). But Pathos, by accident, does not depend on Swift Foundation. Now what?

After browsing the documentation, a pretty good solution emerged: Data is a sequence of bytes! Lets say we hand our users some bytes, they can easily construct a Data from it:

let content: [UInt8] = try readBytes(fromPath "/tmp/test")
Data(bytes: content)

Okay, so this built-in initializer makes [UInt8] an acceptable substitute for returning Data. What can we do about about Data as input? Well, turns out, Data is a Collection of UInt8s! So we can accept Data indirectly like so:

func write<Bytes>(_ bytes: Bytes)
    where Bytes: Collection, Bytes.Element == UInt8
    // blah

User can pass in a Data as argument and it just works™.

The only disadvantage of supporting Data in these ways is that it requires your user to discover it either via your excellent documentation, or through their super good knowledge of Foundation.

Update: this could also be slower than using Data directly. Luckily I'm only doing file I/O here.

But this is pretty nice, regardless.