-
Notifications
You must be signed in to change notification settings - Fork 11k
/
table.move
102 lines (89 loc) · 4.09 KB
/
table.move
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0
/// A table is a map-like collection. But unlike a traditional collection, it's keys and values are
/// not stored within the `Table` value, but instead are stored using Sui's object system. The
/// `Table` struct acts only as a handle into the object system to retrieve those keys and values.
/// Note that this means that `Table` values with exactly the same key-value mapping will not be
/// equal, with `==`, at runtime. For example
/// ```
/// let table1 = table::new<u64, bool>();
/// let table2 = table::new<u64, bool>();
/// table::add(&mut table1, 0, false);
/// table::add(&mut table1, 1, true);
/// table::add(&mut table2, 0, false);
/// table::add(&mut table2, 1, true);
/// // table1 does not equal table2, despite having the same entries
/// assert!(&table1 != &table2);
/// ```
module sui::table {
use sui::dynamic_field as field;
// Attempted to destroy a non-empty table
const ETableNotEmpty: u64 = 0;
public struct Table<phantom K: copy + drop + store, phantom V: store> has key, store {
/// the ID of this table
id: UID,
/// the number of key-value pairs in the table
size: u64,
}
/// Creates a new, empty table
public fun new<K: copy + drop + store, V: store>(ctx: &mut TxContext): Table<K, V> {
Table {
id: object::new(ctx),
size: 0,
}
}
/// Adds a key-value pair to the table `table: &mut Table<K, V>`
/// Aborts with `sui::dynamic_field::EFieldAlreadyExists` if the table already has an entry with
/// that key `k: K`.
public fun add<K: copy + drop + store, V: store>(table: &mut Table<K, V>, k: K, v: V) {
field::add(&mut table.id, k, v);
table.size = table.size + 1;
}
#[syntax(index)]
/// Immutable borrows the value associated with the key in the table `table: &Table<K, V>`.
/// Aborts with `sui::dynamic_field::EFieldDoesNotExist` if the table does not have an entry with
/// that key `k: K`.
public fun borrow<K: copy + drop + store, V: store>(table: &Table<K, V>, k: K): &V {
field::borrow(&table.id, k)
}
#[syntax(index)]
/// Mutably borrows the value associated with the key in the table `table: &mut Table<K, V>`.
/// Aborts with `sui::dynamic_field::EFieldDoesNotExist` if the table does not have an entry with
/// that key `k: K`.
public fun borrow_mut<K: copy + drop + store, V: store>(table: &mut Table<K, V>, k: K): &mut V {
field::borrow_mut(&mut table.id, k)
}
/// Removes the key-value pair in the table `table: &mut Table<K, V>` and returns the value.
/// Aborts with `sui::dynamic_field::EFieldDoesNotExist` if the table does not have an entry with
/// that key `k: K`.
public fun remove<K: copy + drop + store, V: store>(table: &mut Table<K, V>, k: K): V {
let v = field::remove(&mut table.id, k);
table.size = table.size - 1;
v
}
/// Returns true iff there is a value associated with the key `k: K` in table `table: &Table<K, V>`
public fun contains<K: copy + drop + store, V: store>(table: &Table<K, V>, k: K): bool {
field::exists_with_type<K, V>(&table.id, k)
}
/// Returns the size of the table, the number of key-value pairs
public fun length<K: copy + drop + store, V: store>(table: &Table<K, V>): u64 {
table.size
}
/// Returns true iff the table is empty (if `length` returns `0`)
public fun is_empty<K: copy + drop + store, V: store>(table: &Table<K, V>): bool {
table.size == 0
}
/// Destroys an empty table
/// Aborts with `ETableNotEmpty` if the table still contains values
public fun destroy_empty<K: copy + drop + store, V: store>(table: Table<K, V>) {
let Table { id, size } = table;
assert!(size == 0, ETableNotEmpty);
id.delete()
}
/// Drop a possibly non-empty table.
/// Usable only if the value type `V` has the `drop` ability
public fun drop<K: copy + drop + store, V: drop + store>(table: Table<K, V>) {
let Table { id, size: _ } = table;
id.delete()
}
}