Dependability

Enum Dependability 

Source
pub enum Dependability {
    C_VALIDATE,
    C_DTOR_FAIL,
    C_DTOR_BLOCK,
}

Variants§

§

C_VALIDATE

Rust APIs do not generally follow the robustness principle: “be conservative in what you send; be liberal in what you accept”.

Instead, Rust code should enforce the validity of input whenever practical.

Enforcement can be achieved through the following mechanisms (listed in order of preference).

Static enforcement

Choose an argument type that rules out bad inputs.

// For example, prefer
fn foo(a: Ascii) { /* ... */ }
// over
fn foo(a: u8) { /* ... */ }

where Ascii is a wrapper around u8 that guarantees the highest bit is zero; see newtype patterns (C-NEWTYPE) for more details on creating typesafe wrappers.

Static enforcement usually comes at little run-time cost: it pushes the costs to the boundaries (e.g. when a u8 is first converted into an Ascii). It also catches bugs early, during compilation, rather than through run-time failures.

On the other hand, some properties are difficult or impossible to express using types.

Dynamic enforcement

Validate the input as it is processed (or ahead of time, if necessary). Dynamic checking is often easier to implement than static checking, but has several downsides:

  • Runtime overhead (unless checking can be done as part of processing the input).
  • Delayed detection of bugs.
  • Introduces failure cases, either via panic! or Result/Option types, which must then be dealt with by client code.

Dynamic enforcement with debug_assert!

Same as dynamic enforcement, but with the possibility of easily turning off expensive checks for production builds.

Dynamic enforcement with opt-out

Same as dynamic enforcement, but adds sibling functions that opt out of the checking.

The convention is to mark these opt-out functions with a suffix like _unchecked or by placing them in a raw submodule.

The unchecked functions can be used judiciously in cases where (1) performance dictates avoiding checks and (2) the client is otherwise confident that the inputs are valid.

Functions validate their arguments (C-VALIDATE)

§

C_DTOR_FAIL

Destructors are executed while panicking, and in that context a failing destructor causes the program to abort.

Instead of failing in a destructor, provide a separate method for checking for clean teardown, e.g. a close method, that returns a Result to signal problems. If that close method is not called, the Drop implementation should do the teardown and ignore or log/trace any errors it produces.

Destructors never fail (C-DTOR-FAIL)

§

C_DTOR_BLOCK

Similarly, destructors should not invoke blocking operations, which can make debugging much more difficult. Again, consider providing a separate method for preparing for an infallible, nonblocking teardown.

Destructors that may block have alternatives (C-DTOR-BLOCK)

Auto Trait Implementations§

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.