This PR updates the archive package so that it manages more of its own logic. We do this by adding an abstraction called an archive.Manager that embeds an Archive but also adds logic around persisting it to and loading it from a specific file. This makes it easier to use the archive system as a whole.
Now, to create an archive, we create a manager and give it the path to where we want it to store data. We can attempt to load any data that is already present with Load and then we can use it as an archive (the struct embedding means that all methods of an Archive are available on the Manager). When we're done, we can Save back to whatever file it uses.
The system also uses a special function type called an Opener. This is a function that converts a path into a usable file-like io.ReadWriteCloser. Having this component of the system separated out makes it easier to mock opening files for testing purposes and makes it easier to use different types of entities as data stores.
This PR updates the
archive
package so that it manages more of its own logic. We do this by adding an abstraction called anarchive.Manager
that embeds anArchive
but also adds logic around persisting it to and loading it from a specific file. This makes it easier to use the archive system as a whole.Now, to create an archive, we create a manager and give it the path to where we want it to store data. We can attempt to load any data that is already present with
Load
and then we can use it as an archive (the struct embedding means that all methods of an Archive are available on the Manager). When we're done, we canSave
back to whatever file it uses.The system also uses a special function type called an
Opener
. This is a function that converts a path into a usable file-likeio.ReadWriteCloser
. Having this component of the system separated out makes it easier to mock opening files for testing purposes and makes it easier to use different types of entities as data stores.