# Ergonomic Inspect

This guide covers the usage of the
[`fuchsia_inspect_derive`](/src/lib/diagnostics/inspect/derive)
library, and assumes that you are familiar with
[Inspect](/docs/development/inspect)
and have basic experience with the
[`fuchsia_inspect`](/src/lib/diagnostics/inspect/rust) library.

## Overview

The `fuchsia_inspect_derive` library provides ergonomic macros, traits and
smart pointers around the `fuchsia_inspect` library, that makes it easier to
integrate inspect with your Rust code base, by:

- Owning source data and inspect data under the same RAII type
- Being idiomatic. First class support for primitives, common interior
  mutability patterns and async.
- Generating repetitive boilerplate code
- Providing a unified way to [attach a type to inspect](#inspect-attaching)
- Supporting gradual integration with existing code bases, both those that
  don't yet support inspect, and the ones that are integrated with
  `fuchsia_inspect` directly.
- Supporting foreign types that lack inspect integration. See
  [`IDebug<T>`](#idebug) for usage and constraints.

At the same time, it preserves the performance and semantics of a manual inspect
integration, by:

- Committing granular inspect tree modifications, where logical leaf nodes are
  updated independently.
- Applying static dispatch only, to avoid additional runtime overhead.
- Not using any additional synchronization primitives.

### Caveats

When you integrate your Rust code base with this library, be aware that:

- The library mirrors the internal type hierarchy of the Rust program. Limited
  structural modifications such as renaming, flattening and omitting fields are
  supported (similar to [Serde][serde-field-attrs]). If the desired inspect tree
  structure is vastly different from the type hierarchy, you should consider
  using `fuchsia_inspect` directly.
- Some features are not yet supported, requiring you to
  [implement `Inspect` manually](#implement-inspect-manually):
  - Lazy nodes, histograms and inspect arrays.
  - `Option<T>` and other enums.
  - Collection types, such as vectors and maps.
- The library promotes [custom smart pointers](#iowned), which creates another
  layer of data wrapping.


## Quick start {#quick-start}

This section shows an example where you take an existing data structure and
apply inspect to that structure. Let's start with a simple example, a Yak:

```rust
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/rust/ergonomic-inspect/src/main.rs" region_tag="quick_start_before_decl" adjust_indentation="auto" %}
```

Then, consider this construction site:

```rust
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/rust/ergonomic-inspect/src/main.rs" region_tag="quick_start_before_init" adjust_indentation="auto" %}
```

Let's make the yak inspectable. In particular:

- Expose the current hair length
- Expose the number of times the Yak has been shaved
- The credit card number should NOT be exposed

Now use `fuchsia_inspect_derive` to make this Yak inspectable:


```rust
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/rust/ergonomic-inspect/src/main.rs" region_tag="quick_start_after_decl" adjust_indentation="auto" %}
```

Now, in your main program (or in a unit test), construct the yak and attach it
to the inspect tree:


```rust
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/rust/ergonomic-inspect/src/main.rs" region_tag="quick_start_after_init" adjust_indentation="auto" %}
```

Now you have integrated a simple program with Inspect. The rest of this guide
describes the types, traits and macros of this library, and how to apply them to
real world programs.

## Derive `Inspect` {#inspect-derive}

`derive(Inspect)` can be added to any named struct, *but each of its fields
must also implement `Inspect`* (except for `inspect_node` and skipped fields).
The library provides implementations of `Inspect` for several types:

- The [`IOwned` smart pointers](#iowned)
- Many common [interior mutability wrappers](#interior-mutability)
- All inspect properties (`UintProperty`, `StringProperty`, etc) except for
  arrays and histograms
- Other `Inspect` types. [See the section on nesting](#inspect-nesting).

If you add a type which isn't `Inspect`, you get a compiler error:

```rust
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/rust/ergonomic-inspect/src/compiler_errors.rs" region_tag="derive_inspect_unwrapped" adjust_indentation="auto" %}
```

### Nested `Inspect` Types {#inspect-nesting}

`Inspect` types can be freely nested, like so:

```rust
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/rust/ergonomic-inspect/src/main.rs" region_tag="inspect_nested_decl" adjust_indentation="auto" %}
```

### Fields and Attributes {#inspect-attributes}

All fields, except for skipped fields and `inspect_node`, must implement
`Inspect`, either for `&mut T` or `&T`.

If an `inspect_node` field is present, instances will have its own node in the
inspect tree. It must be a `fuchsia_inspect::Node`:

```rust
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/rust/ergonomic-inspect/src/main.rs" region_tag="inspect_node_present_decl" adjust_indentation="auto" %}
```

If `inspect_node` is absent, fields will be attached directly to the parent node
(meaning that the name provided to `with_inspect` will be ignored):

```rust
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/rust/ergonomic-inspect/src/main.rs" region_tag="inspect_node_absent_decl" adjust_indentation="auto" %}
```

If your type needs to add or remove nodes or properties dynamically,
it should own an inspect node. The inspect node is needed when
nodes or properties are added or removed after the initial attachment.

`derive(Inspect)` supports the following field attributes:

- `inspect(skip)`: The field is ignored by inspect.
- `inspect(rename = "foo")`: Use a different name. By default, the field name
  is used.
- `inspect(forward)`: Forwards the attachment to an inner `Inspect` type, omitting one
  layer of nesting from the inspect hierarchy. The type must NOT have an
  `inspect_node` field. Useful for wrapper types. For example:

```rust
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/rust/ergonomic-inspect/src/main.rs" region_tag="inspect_forward_decl" adjust_indentation="auto" %}
```

### Manually Managed Inspect Types

If you are integrating with a code base that uses `fuchsia_inspect` directly,
its types are not be aware of `fuchsia_inspect_derive`. Do not add such
manually managed types as fields to an `Inspect` type directly. Instead,
[implement `Inspect` manually](#implement-inspect-manually) for the type.
Avoid attaching manually outside of the `Inspect` trait,
since attachment in `fuchsia_inspect_derive` occurs after construction.
Attaching in a constructor can silently cause its inspect state to be
absent.

### Attaching to the Inspect Tree {#inspect-attaching}

An inspect type should be attached once, and immediately after instantiation,
using the `with_inspect` extension trait method:

```rust
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/rust/ergonomic-inspect/src/main.rs" region_tag="inspect_node_present_init" adjust_indentation="auto" %}
```

If you have a nested `Inspect` structure, you should only attach the top-level
type. The nested types are attached implicitly:

```rust
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/rust/ergonomic-inspect/src/main.rs" region_tag="inspect_nested_init" adjust_indentation="auto" %}
```

Note that when a `Yak` is constructed from within a `Stable`, there is no
`with_inspect` call present. Instead, the `Yak` is automatically attached as a
child of the `Stable`. However, you can still attach a `Yak` when it is the
top-level type, such as in the unit tests for `Yak`. This allows you to test any
`Inspect` type in isolation.

You can optionally choose to supply inspect nodes in constructors instead of
explicitly calling `with_inspect` at the construction sites. First, ensure that
the type is NOT nested under another `Inspect` type (as this would cause
duplicate attachments). Sedondly, make sure to document this fact clearly,
so the calling user is aware of your attachment convention.

### Interior mutability {#interior-mutability}

In Rust (and particularly `async` Rust), it is common to use interior
mutability. This library provides `Inspect` implementations for several smart
pointers and locks:

- `std`: `Box`, `Arc`, `Rc`, `RefCell`, `Mutex` and `RwLock`
  - Note that `Cell` does NOT work. Instead, upgrade to a `RefCell`.
- `parking_lot`: `Mutex` and `RwLock`
- `futures`: `Mutex`

Generally, interior mutability within a `derive(Inspect)` type just works:

```diff
#[derive(Inspect)]
struct Stable {
-   yak: Yak,
+   yak: Arc<Mutex<Yak>>,
-   horse: Horse,
+   horse: RefCell<Horse>,
    inspect_node: fuchsia_inspect::Node,
}
```

Make sure to put your smart pointers inside your mutability wrapper:

```diff
struct Yak {
-   coins: IValue<Rc<RwLock<u32>>>,  // Won't compile
+   coins: Rc<RwLock<IValue<u32>>>,  // Correct
}
```

If an inner type is behind a lock, attachment will fail if the lock is
acquired by someone else. Hence, always attach immediately after
instantiation.

### Implement `Inspect` Manually {#implement-inspect-manually}

The `derive(Inspect)` derive-macro generates an
`impl Inspect for &mut T { .. }`. Oftentimes, this works fine, but in
some cases you may need to implement `Inspect` manually. Fortunately,
the `Inspect` trait is quite simple:

```rust
trait Inspect {
    /// Attach self to the inspect tree
    fn iattach(self, parent: &Node, name: AsRef<str>) -> Result<(), AttachError>;
}
```

Do not return an `AttachError` for structural errors in the data.
Instead, report the error using logs or an inspect node.
`AttachError` is reserved for irrecoverable invariant errors that
fail the entire attachment.

## `IOwned` Smart Pointers {#iowned}

Smart pointers may sound scary, but you probably use them everyday already. For
instance, `Arc` and `Box` are smart pointers. They are statically dispatched,
and have first-class support in Rust (through [deref coercion]). This makes them
minimally invasive.

`fuchsia_inspect_derive` comes with a few useful smart pointers that implement
`Inspect` and can be used to wrap primitives, debuggable types, and more. They
all share the same behavior: An `IOwned<T>` smart pointer owns a generic
**source type** `T` and some associated **inspect data**.

Here is a demonstration of the `IOwned` API:

```rust
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/rust/ergonomic-inspect/src/main.rs" region_tag="smart_pointers_ivalue" adjust_indentation="auto" %}
```

An `IOwned<T>` smart pointer should not be instantiated directly, but rather one
of its variants:

### `IValue<T>` {#ivalue}

The `IValue<T>` smart pointer wraps a primitive ([or any type `T: Unit`](#unit)).
For example, an `IValue<f32>` is represented as a `DoubleProperty`, and
an `IValue<i16>` is represented as an `IntProperty`.

An `IValue` of a primitive results in the same structure as using a plain
inspect property directly. So, why would you use an `IValue`? If you only
need to write or increment a value, you can use a plain inspect property. If you
also need to read the value, you should use an `IValue`.

### `IDebug<T>` {#idebug}

The `IDebug<T>` smart pointer wraps a debuggable type, and maintains the debug
representation of `T` as a `StringProperty`. This is useful for:

- Foreign types, where adding an inspect implementation is infeasible
- Debugging, to quickly verify some state about your program

Avoid using debug representations in production code, since they come with
the following issues:

- Debug representations are written on every inspect update, which can result in
  unnecessary performance overhead.
- Debug representations can exhaust the space of the inspect VMO, causing
  truncation of the entire inspect state.
- Debug representations cannot be integrated with the privacy pipeline: if any
  PII is exposed as part of the debug string, the entire field must be
  considered PII. Managing your own structured data allows to granularly redact
  fields containing PII.

## The `Unit` Trait {#unit}

The `Unit` trait describes the inspect representation of a type, how to
initialize it, and how to update it. It should be implemented for types that act
as a logical leaf node, and does NOT support per-field updates. This library
provides implementations of `Unit` for most primitives. For example, `u8`,
`u16`, `u32` and `u64` are represented as a `UintProperty`.

### Usage in IValue {#unit-usage}

A `Unit` type should be wrapped in an `IValue<T: Unit>` (see above), for a RAII
managed inspectable type. It is NOT recommended to call methods on `Unit`
directly.

### Derive `Unit` {#unit-derive}

Sometimes a logical `Unit` is a composite type. Unit can be derived for a named
struct, as long as its fields also implement `Unit`. For example:

```rust
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/rust/ergonomic-inspect/src/main.rs" region_tag="unit_plain_decl" adjust_indentation="auto" %}
```

`Unit` can be nested, but keep in mind that all fields are still written at
the same time:

```rust
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/rust/ergonomic-inspect/src/main.rs" region_tag="unit_nested_decl" adjust_indentation="auto" %}
```

#### Attributes {#unit-attributes}

`derive(Unit)` supports the following field attributes:

- `inspect(skip)`: The field is ignored by inspect.
- `inspect(rename = "foo")`: Use a different name. By default, the field name
  is used.

[deref coercion]:
https://doc.rust-lang.org/1.27.2/book/second-edition/ch15-02-deref.html

[serde-field-attrs]:
https://serde.rs/field-attrs.html
