But this kinda expects that your USB driver is the application code too, no? This is less of a driver and more of a library + program. If I have, say, a USB to Ethernet device, how do I hook this into the ethernet adapter subsystem?
On Linux you could create a tun/tap device from your application and translate data sent over that to requests sent to the ethernet adapter.
Of course, when you're doing these things in userspace you either need some way of communicating with the Kernel or for the other subsystems to be in userspace as well.
Things which are relatively standard tend to get good generic support: Ethernet devices will generally be USB/CDC/ECM or RNDIS, for example. That may Just Work (tm) if it has the right descriptors.
The userland approach is much more useful for weird or custom devices. In particular, on Windows you can do one of these user space "drivers" without having to bother with driver signing, and if you use libusb it will be portable too.
(I maintain a small USB DFU based tool for work)