Naming

Enum Naming 

Source
pub enum Naming {
    C_CASE,
    C_CONV,
    C_GETTER,
    C_ITER,
    C_ITER_TY,
    C_FEATURE,
    C_WORD_ORDER,
}
Expand description

Naming conventions and guidelines for Rust APIs

Variants§

§

C_CASE

In general, Rust tends to use UpperCamelCase for “type-level” constructs (types and traits) and snake_case for “value-level” constructs.

Item Convention
Crates unclear
Modules snake_case
Crates unclear
Types UpperCamelCase
Traits UpperCamelCase
Enum variants UpperCamelCase
Functions snake_case
Methods snake_case
General constructors new or with_more_details
Conversion constructors from_some_other_type
Macros snake_case!
Local variables snake_case
Statics SCREAMING_SNAKE_CASE
Constants SCREAMING_SNAKE_CASE
Type parameters concise UpperCamelCase, usually single uppercase letter: T
Lifetimes short lowercase, usually a single letter: 'a, 'de, 'src
Features unclear but see C-FEATURE
In UpperCamelCase, acronyms and contractions of compound words count as one word: use Uuid rather than UUID, Usize rather than USize or Stdin rather than StdIn. In snake_case, acronyms and contractions are lower-cased: is_xid_start.

In snake_case or SCREAMING_SNAKE_CASE, a “word” should never consist of a single letter unless it is the last “word”. So, we have btree_map rather than b_tree_map, but PI_2 rather than PI2.

Crate names should not use -rs or -rust as a suffix or prefix. Every crate is Rust! It serves no purpose to remind users of this constantly.

Casing conforms to RFC 430

§

C_CONV

Conversions should be provided as methods, with names prefixed as follows:

Prefix Cost Ownership
as_ Free borrowed -> borrowed
to_ Expensive borrowed -> borrowed borrowed -> owned (non-Copy types) owned -> owned (Copy types)
into_ Variable owned -> owned (non-Copy types)

For example:

str::as_bytes() gives a view of a str as a slice of UTF-8 bytes, which is free. The input is a borrowed &str and the output is a borrowed &u8.

Path::to_str performs an expensive UTF-8 check on the bytes of an operating system path. The input and output are both borrowed. It would not be correct to call this as_str because this method has nontrivial cost at runtime.

str::to_lowercase() produces the Unicode-correct lowercase equivalent of a str, which involves iterating through characters of the string and may require memory allocation. The input is a borrowed &str and the output is an owned String.

f64::to_radians() converts a floating point quantity from degrees to radians. The input is f64. Passing a reference &f64 is not warranted because f64 is cheap to copy. Calling the function into_radians would be misleading because the input is not consumed.

String::into_bytes() extracts the underlying Vec of a String, which is free. It takes ownership of a String and returns an owned Vec.

BufReader::into_inner() takes ownership of a buffered reader and extracts out the underlying reader, which is free. Data in the buffer is discarded.

BufWriter::into_inner() takes ownership of a buffered writer and extracts out the underlying writer, which requires a potentially expensive flush of any buffered data.

Conversions prefixed as_ and into_ typically decrease abstraction, either exposing a view into the underlying representation (as) or deconstructing data into its underlying representation (into). Conversions prefixed to_, on the other hand, typically stay at the same level of abstraction but do some work to change from one representation to another.

When a type wraps a single value to associate it with higher-level semantics, access to the wrapped value should be provided by an into_inner() method. This applies to wrappers that provide buffering like BufReader , encoding or decoding like GzDecoder , atomic access like AtomicBool , or any similar semantics.

If the mut qualifier in the name of a conversion method constitutes part of the return type, it should appear as it would appear in the type. For example Vec::as_mut_slice returns a mut slice; it does what it says. This name is preferred over as_slice_mut.

// Return type is a mut slice.
fn as_mut_slice(&mut self) -> &mut [T];

More examples from the standard library

Ad-hoc conversions follow as_, to_, into_ conventions

§

C_GETTER

With a few exceptions, the get_ prefix is not used for getters in Rust code.

The get naming is used only when there is a single and obvious thing that could reasonably be gotten by a getter. For example Cell::get accesses the content of a Cell.

For getters that do runtime validation such as bounds checking, consider adding unsafe _unchecked variants. Typically those will have the following signatures.

fn get(&self, index: K) -> Option<&V>;
fn get_mut(&mut self, index: K) -> Option<&mut V>;
unsafe fn get_unchecked(&self, index: K) -> &V;
unsafe fn get_unchecked_mut(&mut self, index: K) -> &mut V;

The difference between getters and conversions (C-CONV) can be subtle and is not always clear-cut. For example TempDir::path can be understood as a getter for the filesystem path of the temporary directory, while TempDir::into_path is a conversion that transfers responsibility for deleting the temporary directory to the caller. Since path is a getter, it would not be correct to call it get_path or as_path.

Examples from the standard library

Getter names follow Rust convention (C-GETTER)

§

C_ITER

Per RFC 199.

For a container with elements of type U, iterator methods should be named:

fn iter(&self) -> Iter             // Iter implements Iterator<Item = &U>
fn iter_mut(&mut self) -> IterMut  // IterMut implements Iterator<Item = &mut U>
fn into_iter(self) -> IntoIter     // IntoIter implements Iterator<Item = U>

This guideline applies to data structures that are conceptually homogeneous collections. As a counterexample, the str type is slice of bytes that are guaranteed to be valid UTF-8. This is conceptually more nuanced than a homogeneous collection so rather than providing the iter/iter_mut/into_iter group of iterator methods, it provides str::bytes to iterate as bytes and str::chars to iterate as chars.

This guideline applies to methods only, not functions. For example percent_encode from the url crate returns an iterator over percent-encoded string fragments. There would be no clarity to be had by using an iter/iter_mut/into_iter convention.

Examples from the standard library

Methods on collections that produce iterators follow iter, iter_mut, into_iter (C-ITER)

§

C_ITER_TY

A method called into_iter() should return a type called IntoIter and similarly for all other methods that return iterators.

This guideline applies chiefly to methods, but often makes sense for functions as well. For example the percent_encode function from the url crate returns an iterator type called PercentEncode.

These type names make the most sense when prefixed with their owning module, for example vec::IntoIter.

Iterator type names match the methods that produce them

§

C_FEATURE

Do not include words in the name of a Cargo feature that convey zero meaning, as in use-abc or with-abc. Name the feature abc directly.

Feature names are free of placeholder words (C-FEATURE)

§

C_WORD_ORDER

All of these use verb-object-error word order. If we were adding an error to represent an address failing to parse, for consistency we would want to name it in verb-object-error order like ParseAddrError rather than AddrParseError.

The particular choice of word order is not important, but pay attention to consistency within the crate and consistency with similar functionality in the standard library.

Names use a consistent word order (C-WORD-ORDER)

Trait Implementations§

Source§

impl Debug for Naming

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl Freeze for Naming

§

impl RefUnwindSafe for Naming

§

impl Send for Naming

§

impl Sync for Naming

§

impl Unpin for Naming

§

impl UnwindSafe for Naming

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.