sui::bagA bag is a heterogeneous map-like collection. The collection is similar to sui::table in that
its keys and values are not stored within the Bag value, but instead are stored using Sui’s
object system. The Bag struct acts only as a handle into the object system to retrieve those
keys and values.
Note that this means that Bag values with exactly the same key-value mapping will not be
equal, with ==, at runtime. For example
let bag1 = bag::new();
let bag2 = bag::new();
bag::add(&mut bag1, 0, false);
bag::add(&mut bag1, 1, true);
bag::add(&mut bag2, 0, false);
bag::add(&mut bag2, 1, true);
// bag1 does not equal bag2, despite having the same entries
assert!(&bag1 != &bag2);
At it’s core, sui::bag is a wrapper around UID that allows for access to
sui::dynamic_field while preventing accidentally stranding field values. A UID can be
deleted, even if it has dynamic fields associated with it, but a bag, on the other hand, must be
empty to be destroyed.
Bagnewaddborrowborrow_mutremovecontainscontains_with_typelengthis_emptydestroy_emptyuse std::ascii;
use std::bcs;
use std::option;
use std::string;
use std::vector;
use sui::address;
use sui::dynamic_field;
use sui::hex;
use sui::object;
use sui::tx_context;
Bagpublic struct Bag has key, store
id: sui::object::UID
size: u64
const EBagNotEmpty: u64 = 0;
newCreates a new, empty bag
public fun new(ctx: &mut sui::tx_context::TxContext): sui::bag::Bag
addAdds a key-value pair to the bag bag: &mut Bag
Aborts with sui::dynamic_field::EFieldAlreadyExists if the bag already has an entry with
that key k: K.
public fun add<K: copy, drop, store, V: store>(bag: &mut sui::bag::Bag, k: K, v: V)
public fun add<K: copy + drop + store, V: store>(bag: &mut Bag, k: K, v: V) {
field::add(&mut bag.id, k, v);
bag.size = bag.size + 1;
}
borrowImmutable borrows the value associated with the key in the bag bag: &Bag.
Aborts with sui::dynamic_field::EFieldDoesNotExist if the bag does not have an entry with
that key k: K.
Aborts with sui::dynamic_field::EFieldTypeMismatch if the bag has an entry for the key, but
the value does not have the specified type.
public fun borrow<K: copy, drop, store, V: store>(bag: &sui::bag::Bag, k: K): &V
public fun borrow<K: copy + drop + store, V: store>(bag: &Bag, k: K): &V {
field::borrow(&bag.id, k)
}
borrow_mutMutably borrows the value associated with the key in the bag bag: &mut Bag.
Aborts with sui::dynamic_field::EFieldDoesNotExist if the bag does not have an entry with
that key k: K.
Aborts with sui::dynamic_field::EFieldTypeMismatch if the bag has an entry for the key, but
the value does not have the specified type.
public fun borrow_mut<K: copy, drop, store, V: store>(bag: &mut sui::bag::Bag, k: K): &mut V
public fun borrow_mut<K: copy + drop + store, V: store>(bag: &mut Bag, k: K): &mut V {
field::borrow_mut(&mut bag.id, k)
}
removeMutably borrows the key-value pair in the bag bag: &mut Bag and returns the value.
Aborts with sui::dynamic_field::EFieldDoesNotExist if the bag does not have an entry with
that key k: K.
Aborts with sui::dynamic_field::EFieldTypeMismatch if the bag has an entry for the key, but
the value does not have the specified type.
public fun remove<K: copy, drop, store, V: store>(bag: &mut sui::bag::Bag, k: K): V
public fun remove<K: copy + drop + store, V: store>(bag: &mut Bag, k: K): V {
let v = field::remove(&mut bag.id, k);
bag.size = bag.size - 1;
v
}
containsReturns true iff there is an value associated with the key k: K in the bag bag: &Bag
public fun contains<K: copy, drop, store>(bag: &sui::bag::Bag, k: K): bool
public fun contains<K: copy + drop + store>(bag: &Bag, k: K): bool {
field::exists_<K>(&bag.id, k)
}
contains_with_typeReturns true iff there is an value associated with the key k: K in the bag bag: &Bag
with an assigned value of type V
public fun contains_with_type<K: copy, drop, store, V: store>(bag: &sui::bag::Bag, k: K): bool
public fun contains_with_type<K: copy + drop + store, V: store>(bag: &Bag, k: K): bool {
field::exists_with_type<K, V>(&bag.id, k)
}
lengthReturns the size of the bag, the number of key-value pairs
public fun length(bag: &sui::bag::Bag): u64
is_emptyReturns true iff the bag is empty (if length returns 0)
public fun is_empty(bag: &sui::bag::Bag): bool
destroy_emptyDestroys an empty bag
Aborts with EBagNotEmpty if the bag still contains values
public fun destroy_empty(bag: sui::bag::Bag)
public fun destroy_empty(bag: Bag) {
let Bag { id, size } = bag;
assert!(size == 0, EBagNotEmpty);
id.delete()
}