fileserver/lib/restbed-4.8/documentation/STANDARDS.md

266 lines
7.0 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Overview
--------
This document sets out the expected coding style for those who wish to participate in this project. With this standard we will maintain a readable codebase that can be easily cannibalised by new and old developers alike.
To ensure the codebase meets this standard please install the supplied [GIT pre-commit](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) hook into your local copy. You're also required to install the [Artistic Style](http://astyle.sourceforge.net/) tool on your system for this hook to be successful; you must have version 2.05 or greater installed.
```
cd restbed/
cp tool/git/pre-commit .git/hooks
chmod +x .git/hooks/pre-commit
```
**most importantly:** "know when to be inconsistent -- sometimes the style guide just doesn't apply. When in doubt, use your best judgment. Look at other examples and decide what looks best. And don't hesitate to ask!" -- Guido van Rossum, Barry Warsaw, Nick Coghlan.
Interpretation
--------------
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in [RFC 2119](http://tools.ietf.org/pdf/rfc2119.pdf).
Table of Contents
-----------------
1. [Overview](#overview)
2. [Interpretation](#interpretation)
3. [Brackets](#brackets)
4. [Indentation](#indentation)
5. [Comments](#comments)
6. [Properties/Variables](#propertiesvariables)
7. [Classes](#classes)
8. [Enumerations](#enumerations)
9. [Structures](#structures)
10. [Methods/Functions](#methodsfunctions)
11. [Whitespace](#whitespace)
12. [Pointers/References](#pointersreferences)
13. [Exceptions](#exceptions)
14. [Namespaces](#namespaces)
15. [Optimisations](#optimisations)
### Brackets
- Allman style broken braces, and avoid unbraced one line conditional statements.
```C++
if ( condition == true )
{
...
}
else
{
...
}
```
### Indentation
- Do **not** use tabs. All indentation is of 4 spaces.
- Class, Namespace, Struct, If, For, Switch, etc.. statements **must** be indented.
```C++
namespace transport
{
class Car( void )
{
public:
Car( const int number_of_wheels ) : m_number_of_wheels
{
switch( m_number_of_wheels )
{
case 1:
break;
default:
break;
}
}
private:
uint8_t m_number_of_wheels;
}
}
```
### Comments
- Comments **should** be avoided as they add an additional layer of management and/or technical-debt.
- Commenting is just as ineffective as poorly readable code.
- Code should be self documenting with descriptive naming conventions applied to functions, variables, files, directories, etc...
- Commenting may be a sign you need to split the logic into multiple manageable blocks.
### Properties/Variables
- Property and Variables names **must** follow the [Snake-case naming convention](https://en.wikipedia.org/wiki/snake_case).
- Property and Variables **must** be initialised to a known state on declaration.
```C++
int limit = 0;
int person_age = 21;
string name = String::empty;
```
### Classes
- Class property names **must** be prefixed with `m_` and follow the [Snake-case naming convention](https://en.wikipedia.org/wiki/snake_case).
- Class properties **must** be initialised to a known state on instance creation.
- Class properties **must** be private in scope.
- Class getter/setter accessor methods **must not** return non-const pointers/references.
- There **must** be **no** using namespace declarations in class header files.
- Forward declarations are favoured over `#include` within class header files; with the exception of the standard template library.
- Empty method bodies (when unavoidable) *shall* be marked with a single return.
- Public classes **must** implement an [opaque pointer](http://en.wikipedia.org/wiki/Opaque_pointer).
- Class names **must** start each word boundary with an UPPERCASED letter.
```C++
class Person
{
public:
Person( void ) : m_age( 0 )
{
return;
}
int get_age( void ) const
{
return m_age;
}
void set_age( const int value )
{
m_age = value;
}
private:
int m_age;.
}
```
### Enumerations
- Enumerations **must** be strongly typed.
- Enumeration fields **must** be UPPERCASED.
- Enumeration fields **must** be initialised to a known state.
- Enumeration names **must** start each word boundary with an UPPERCASED letter.
```C++
enum LogLevel : int
{
INFO = 0000,
DEBUG = 1000,
FATAL = 2000,
ERROR = 3000,
WARNING = 4000,
SECURITY = 5000
}
```
### Structures
- Structure property names **must** follow the [Snake-case naming convention](https://en.wikipedia.org/wiki/snake_case).
- Structure properties **must** be initialised to a known state on instance creation.
- Structure names **must** start each word boundary with an UPPERCASED letter.
```C++
struct HttpRequest
{
Bytes body = { };
uint16_t port = 80;
double version = 1.1;
std::string host = "";
std::string path = "/";
std::string method = "GET";
std::multimap< std::string, std::string > headers { };
}
```
### Methods/Functions
- Functions and Methods **must** use the [Snake-case naming convention](https://en.wikipedia.org/wiki/snake_case).
- Functions and Methods **should** perform one mental operation which is reflected in their name.
- Function and Method declarations **should** avoid similar argument types.
- It is recommended that Functions and Methods are no greater than 70 lines of code. If you find that the [LOC](https://en.wikipedia.org/wiki/Source_lines_of_code) exceed this limit, it may be an indication that it is performing more than one mental operation; see rule 2.
```C++
int ping( Hostname hostname, Interface interface, int16_t port )
{
auto port = port;
auto hostname = hostname.to_string( );
auto interface = hostname.to_string( )
...
return ttl;
}
```
### Whitespace
- Whitespace is free, don't be scared to use it.
```C++
int process_exit_status = 0;
const string filename = "/bin/ls";
do
{
Process reaction = load_process( filename );
reaction.run( );
process_exit_status = reaction.get_exit_status( );
}
while ( process_exit_status not_eq -1 );
```
### Pointers/References
- Pointers and References **must** be aligned to the data type (left).
```C++
int* age = nullptr;
char* forename = nullptr;
string& surname = m_surname;
```
### Exceptions
- Logic within catch-blocks **must** be short & sweet.
- Name exceptions per Java styling.
```C++
try
{
start( );
}
catch ( const invalid_argument& ia )
{
stop( );
}
catch ( const runtime_error& re )
{
stop( );
}
catch ( const exception& ex )
{
stop( );
}
```
### Namespaces
- **Do not** include entire Namespaces, import only the artifact you're interested in.
- Namespace names **must only** contain lowercased letters.
```C++
using std::mutex;
using std::string;
using std::thread;
namespace restbed
{
...
}
```
### Optimisations
- Avoid premature optimisation, **readable, maintainable code is more important**.