Guidelines for Rust code
local rules
- Use
log!
for output for debugging (useprintln!
etc. for output processing that is also necessary for release). - Unused or internal variables/methods (private and used only for specific functions) must be prefixed with
_
. If you want to avoid conflicts with reserved words, add one_
to the end. - Use clippy. However, some rules are not reasonable, so you can ignore rules other than
deny
by using#[allow(clippy::...)]
.
Recommended code
- Define and use domain-specific Enums instead of numeric enumerations or bools.
- Keep access modifiers to a minimum. Prioritize using
pub(mod)
orpub(crate)
even when publishing. - Convert an iterable object in a for expression explicitly to an iterator (
for i in x.iter()
instead offor i in x
). - Lazy evaluation. For example, if
default
is non-literal, useunwrap_or_else
instead ofunwrap_or
.
Code not encouraged
- Make heavy use of return type overloading. Specifically code that uses a lot of non-obvious
.into
. This is because type inference results can be counter-intuitive. In this case it is recommended to usefrom
instead. - Make heavy use of
Deref
. This effectively poses the same problem as inheritance.
Code that makes decisions based on context
- Define unused helper methods.
- Use
unwrap
andclone
a lot. In some cases there is nothing better than doing so.
Dependencies
Dependencies should be minimized as much as possible, and those that are necessary should be implemented by the Erg developing team. External dependencies are allowed only if they are extremely difficult to implement or hardware-dependent (e.g. libc
, winapi
), or crate without external dependencies may be used (e.g. unicode-xid
). Otherwise, they may be allowed as optional dependencies (e.g. https client). In all cases, well-maintained and widely-used ones should be selected.
This rule applies only to the Erg compiler; Erg tools and libraries are free to add their own dependencies.