imag/doc/src/03010-conventions.md

96 lines
3.6 KiB
Markdown
Raw Normal View History

# Conventions, best practices
2017-10-14 13:30:06 +00:00
This section goes about best practices in the imag codebase. It is mainly
focused on developers, but a user may read it for getting to know how imag
works.
2017-10-14 13:30:06 +00:00
Lets work our way up from the store and how to extend it to the commandline user
interface.
## Store and Entry functionality
2017-10-14 13:30:06 +00:00
A `Entry` does not offer much functionality by itself. So its the job of
libraries to _extend_ their functionality. This should never be done by wrapping
the `Entry` type itself but by providing and implementing an extension trait on
it.
2017-10-14 13:30:06 +00:00
Same goes for extending the `Store` type: never wrap it, always provide an
extension trait for it.
2017-10-14 13:30:06 +00:00
These two rules ensure that the type does not lose any functionality from a
wrapping. `Deref` could do that, but not over muliple levels, so extension
traits it is. It also most likely results in functions inside the extension
trait which all return a `Result<_, _>`.
## Libraries
2017-10-14 13:30:06 +00:00
In the next few sections, conventions and best practices for writing a imag
library are written down.
2017-10-14 13:30:06 +00:00
A developer of imag should read this carefully, a user may skip this section or
cross-read it for better understanding of the imag project.
### Library naming
2017-10-14 13:30:06 +00:00
Libraries which provide functionality for entries or the store (most likely
entries or both) should be named "libimagentrything" whereas "thing" stands for
what the library provides.
2017-10-14 13:30:06 +00:00
All other libraries should be prefixed with "libimag" at least. Most likely, one
will not write such a library but rather a "libimagentrything" library.
### Library scope
2017-10-14 13:30:06 +00:00
A library should never introduce utility functionality which could be useful for
other libraries as well. If there is no such functionality available, the
"libimagutil" might be a place where such a function would be put, or, if not
yet available, a "libimagentryutil" could be created.
2017-10-14 13:30:06 +00:00
If a library has to introduce free functions in its public interface, one should
think hard whether this is really necessary.
### Library error types/kinds
2017-10-14 13:30:06 +00:00
Libraries must use the "libimagerror" tools to create error types and kinds.
Most likely, a library needs some kinds for wrapping the errors from underlying
libraries, such as the store itself.
2017-10-14 13:30:06 +00:00
A library must _never_ introduce multiple error types, but is free to introduce
as many error kinds as required. Indeed, more kinds is better than fewer.
### Libraries with commandline frontends
2017-10-14 13:30:06 +00:00
Libraries with commandline frontends provide end-user functionality. Normally,
they depend on one or more "libimagentrything" libraries. They should be named
"libimagthing", though. For example: "libimagdiary", "libimagtimetrack" or
"libimagwiki", whereas the commandline frontends would be "imag-diary",
"imag-timetrack" and "imag-wiki", respectively.
2017-10-14 13:30:06 +00:00
If such a library needs to depend on another "libimagthing", for example if
"libimagdiary" needs to depend on "libimagnote", one should think about this and
whether the functionality could ve outsourced to a more general
"libimagentrything". It is not forbidden, though.
2017-10-14 13:30:06 +00:00
A library which implements a functionality for imag may contain helper functions
for commandline stuff, but that is discouraged.
### Library testing
2017-10-14 13:30:06 +00:00
All libraries should be tested as much as possible. Sometimes it may not be
possible without a lot of effort, but still: more tests = better!
## Commandline tools
2017-10-14 13:30:06 +00:00
The next few sections describe how the commandline frontends are implemented.
Each imag functionality (or module) has its own library and a commandline
frontend for it.
2017-10-14 13:30:06 +00:00
The commandline frontends do contain little to no functionality. They simply
translate the commandline parameters and options to calls to the appropriate
library functions.
## Commandline tool testing
## Commandline interface