ClientUtils.Harness.Onboarding.Port (client_utils v0.1.30)
View SourceCalls an io: adapter — a module, or a module paired with the thing it acts on.
Why the names are what they are
These four operations are read_file/2, write_file/3, file_exists?/2 and
cmd/4 because that is CodeMySpec.Environments' contract, verbatim. A host
that already has a filesystem abstraction passes {ThatModule, its_handle}
and writes no adapter at all — CodeMySpec passes
{CodeMySpec.Environments, env}.
The port used to name them read/2, write/3, exists?/2, cmd/3 and take
a bare root, which had two consequences. A host with state could not use it:
CodeMySpec's specs drive a :memory environment holding an Agent pid in
ref, and no adapter given only a path can find that agent — so the single
case this port was justified by ("CodeMySpec passes an adapter over its own
Environments", written into c570d32 as though it were already true) was
the one it could not serve, and CodeMySpec kept a second implementation of
onboard/2 and check/2 instead. And a host without state still had to write
a translation module whose whole content was renaming read to read_file.
Naming the port after an interface a caller already implements costs this
library nothing — its own FileIO is the only other implementation and it is
ours to shape — and costs the caller nothing at all, which is the point.
The shapes
{module, state}—module.read_file(state, path). The state is opaque here; it is whatever the host needs and is passed straight back.module—module.read_file(root, path). The root is the state, which is allFileIOhas ever needed.
A generated application passes neither and gets FileIO.
Summary
Functions
The module an adapter dispatches to.
Types
Functions
The module an adapter dispatches to.
Exposed so a host can assert the adapter it passed is the one being called — the check whose absence let this port go unused for a week while its own documentation said otherwise.