Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document Column #202

Open
wants to merge 4 commits into
base: storey-map
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 138 additions & 0 deletions src/pages/storey/containers/column.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,141 @@ tags: ["storey", "containers"]
import { Callout } from "nextra/components";

# Column

A [`Column`] is a collection of items indexed by auto-incrementing `u32` keys. This might sound
similar to a relational database table; in fact, it is a good analogy.

A [`Column`] makes it efficient to push items to it and access the last element.

<Callout>
It should be noted that in a future version indexing will start at `1`, not `0`.

This change will also break existing contracts that rely on the current `Column` implementation!

</Callout>

## Examples

### Storing a message log

Let's say you want to store a log of messages. You can do this with a `Column<String>`.

```rust template="storage" showLineNumbers {6,8,10,12}
use cw_storey::containers::Column;
use cw_storey::CwStorage;

const MESSAGES_IX: u8 = 1;

let messages: Column<String> = Column::new(MESSAGES_IX);
let mut cw_storage = CwStorage(&mut storage);
let mut access = messages.access(&mut cw_storage);

access.push(&"Hello, world!".to_string()).unwrap();

assert_eq!(access.get(0).unwrap(), Some("Hello, world!".to_string()));
```

- _line 6:_ Here we construct the `Column` facade. The constructor takes a key, which is the prefix
of the keys in the underlying storage backend.
- _line 8:_ The [`access`] method returns a [`ColumnAccess`] entity, which allows manipulating the
column.
- _line 10:_ Here we push a message to the column.
- _line 12:_ We check that the message is stored correctly.

#### Iterating over the messages

As with [`Map`], we can iterate over all messages.

```rust template="storage" showLineNumbers {4, 17}
use cw_storey::containers::{Column, Item};
use cw_storey::CwStorage;

use storey::containers::IterableAccessor as _;

const MESSAGES_IX: u8 = 1;

let messages: Column<String> = Column::new(MESSAGES_IX);
let mut cw_storage = CwStorage(&mut storage);
let mut access = messages.access(&mut cw_storage);

// populate the column
access.push(&"Hello, world!".to_string()).unwrap();
access.push(&"My name is Bob.".to_string()).unwrap();
access.push(&"Hell is empty and all the devils are here.".to_string()).unwrap();

let messages: Vec<_> = access.pairs().collect::<Result<_, _>>().unwrap();

assert_eq!(messages, vec![
(0, "Hello, world!".to_string()),
(1, "My name is Bob.".to_string()),
(2, "Hell is empty and all the devils are here.".to_string()),
]);
```

- _line 4:_ We import the `IterableAccessor` trait to use iteration methods.
- _line 17:_ The `pairs` method produces an iterator over tuples of `(index, value)`. In this case,
we collect the iterator into a `Vec` for ease of making our assertion later.

Similarly to [`Map`], you can use the [`keys`], [`values`], and [`pairs`] methods to iterate over
the items.

#### Bounded iteration

If you want to perform bounded iteration, it is possible. This time you need the
[`BoundedIterableAccessor`] trait, and the relevant methods are [`bounded_pairs`], [`bounded_keys`],
and [`bounded_values`].

The following example is the same as the previous one except for the bounds found in line 17, and
the limited results.

<Callout>
Currently, the lower bound is inclusive, and the upper bound is exclusive.

This will change in a future version, where you'll be able to choose between inclusive and exclusive
bounds as suits you.

</Callout>

```rust template="storage" showLineNumbers {4, 17}
use cw_storey::containers::{Column, Item};
use cw_storey::CwStorage;

use storey::containers::BoundedIterableAccessor as _;

const MESSAGES_IX: u8 = 1;

let messages: Column<String> = Column::new(MESSAGES_IX);
let mut cw_storage = CwStorage(&mut storage);
let mut access = messages.access(&mut cw_storage);

// populate the column
access.push(&"Hello, world!".to_string()).unwrap();
access.push(&"My name is Bob.".to_string()).unwrap();
access.push(&"Hell is empty and all the devils are here.".to_string()).unwrap();

let messages: Vec<_> = access.bounded_pairs(Some(0), Some(2)).collect::<Result<_, _>>().unwrap();

assert_eq!(messages, vec![
(0, "Hello, world!".to_string()),
(1, "My name is Bob.".to_string()),
]);
```

[`Column`]: https://docs.rs/storey/latest/storey/containers/struct.Column.html
[`access`]: https://docs.rs/storey/latest/storey/containers/struct.Column.html#method.access
[`ColumnAccess`]: https://docs.rs/storey/latest/storey/containers/struct.ColumnAccess.html
[`keys`]: https://docs.rs/storey/latest/storey/containers/struct.ColumnAccess.html#method.keys
[`values`]: https://docs.rs/storey/latest/storey/containers/struct.ColumnAccess.html#method.values
[`pairs`]: https://docs.rs/storey/latest/storey/containers/struct.ColumnAccess.html#method.pairs
[`Map`]: https://docs.rs/storey/latest/storey/containers/map/struct.Map.html
[`MapAccess`]: https://docs.rs/storey/latest/storey/containers/map/struct.MapAccess.html
[`ItemAccess`]: https://docs.rs/storey/latest/storey/containers/struct.ItemAccess.html
[`IterableAccessor`]: https://docs.rs/storey/latest/storey/containers/trait.IterableAccessor.html
[`BoundedIterableAccessor`]:
https://docs.rs/storey/latest/storey/containers/trait.BoundedIterableAccessor.html
[`bounded_pairs`]:
https://docs.rs/storey/latest/storey/containers/trait.BoundedIterableAccessor.html#method.bounded_pairs
[`bounded_keys`]:
https://docs.rs/storey/latest/storey/containers/trait.BoundedIterableAccessor.html#method.bounded_keys
[`bounded_values`]:
https://docs.rs/storey/latest/storey/containers/trait.BoundedIterableAccessor.html#method.bounded_values
Loading