Saltearse al contenido

property_map - [testnet]

Esta página aún no está disponible en tu idioma.

PropertyMap is a specialization of SimpleMap for Tokens. It maps a String key to a PropertyValue that consists of type (string) and value (vector) It provides basic on-chain serialization of primitive and string to property value with type information It also supports deserializing property value to it original type.

use 0x1::bcs;
use 0x1::error;
use 0x1::from_bcs;
use 0x1::simple_map;
use 0x1::string;
use 0x1::type_info;

Constants

The property key already exists

const EKEY_AREADY_EXIST_IN_PROPERTY_MAP: u64 = 1;

Property key and type count don’t match

const EKEY_COUNT_NOT_MATCH_TYPE_COUNT: u64 = 5;

Property key and value count don’t match

const EKEY_COUNT_NOT_MATCH_VALUE_COUNT: u64 = 4;

The name (key) of the property is too long

const EPROPERTY_MAP_NAME_TOO_LONG: u64 = 7;

The property doesn’t exist

const EPROPERTY_NOT_EXIST: u64 = 3;

The number of property exceeds the limit

const EPROPERTY_NUMBER_EXCEED_LIMIT: u64 = 2;

Property type doesn’t match

const ETYPE_NOT_MATCH: u64 = 6;

The maximal number of property that can be stored in property map

const MAX_PROPERTY_MAP_SIZE: u64 = 1000;
const MAX_PROPERTY_NAME_LENGTH: u64 = 128;

Structs

PropertyMap

struct PropertyMap has copy, drop, store
Fields
map: simple_map::SimpleMap<string::String, property_map::PropertyValue>

PropertyValue

struct PropertyValue has copy, drop, store
Fields
value: vector<u8>
type: string::String

Functions

new

public fun new(keys: vector<string::String>, values: vector<vector<u8>>, types: vector<string::String>): property_map::PropertyMap
Implementation
public fun new(
keys: vector<String>,
values: vector<vector<u8>>,
types: vector<String>
): PropertyMap {
let length = keys.length();
assert!(length <= MAX_PROPERTY_MAP_SIZE, error::invalid_argument(EPROPERTY_NUMBER_EXCEED_LIMIT));
assert!(length == values.length(), error::invalid_argument(EKEY_COUNT_NOT_MATCH_VALUE_COUNT));
assert!(length == types.length(), error::invalid_argument(EKEY_COUNT_NOT_MATCH_TYPE_COUNT));
let properties = empty();
for (i in 0..length) {
let key = keys[i];
assert!(key.length() <= MAX_PROPERTY_NAME_LENGTH, error::invalid_argument(EPROPERTY_MAP_NAME_TOO_LONG));
properties.map.add(
key,
PropertyValue { value: values[i], type: types[i] }
);
};
properties
}

new_with_key_and_property_value

Create property map directly from key and property value

public fun new_with_key_and_property_value(keys: vector<string::String>, values: vector<property_map::PropertyValue>): property_map::PropertyMap
Implementation
public fun new_with_key_and_property_value(
keys: vector<String>,
values: vector<PropertyValue>
): PropertyMap {
let length = keys.length();
assert!(length <= MAX_PROPERTY_MAP_SIZE, error::invalid_argument(EPROPERTY_NUMBER_EXCEED_LIMIT));
assert!(length == values.length(), error::invalid_argument(EKEY_COUNT_NOT_MATCH_VALUE_COUNT));
let properties = empty();
for (i in 0..length) {
let key = keys[i];
let val = values[i];
assert!(key.length() <= MAX_PROPERTY_NAME_LENGTH, error::invalid_argument(EPROPERTY_MAP_NAME_TOO_LONG));
properties.add(key, val);
};
properties
}

empty

public fun empty(): property_map::PropertyMap
Implementation
public fun empty(): PropertyMap {
PropertyMap {
map: simple_map::create<String, PropertyValue>(),
}
}

contains_key

public fun contains_key(self: &property_map::PropertyMap, key: &string::String): bool
Implementation
public fun contains_key(self: &PropertyMap, key: &String): bool {
self.map.contains_key(key)
}

add

public fun add(self: &mut property_map::PropertyMap, key: string::String, value: property_map::PropertyValue)
Implementation
public fun add(self: &mut PropertyMap, key: String, value: PropertyValue) {
assert!(key.length() <= MAX_PROPERTY_NAME_LENGTH, error::invalid_argument(EPROPERTY_MAP_NAME_TOO_LONG));
assert!(self.map.length() < MAX_PROPERTY_MAP_SIZE, error::invalid_state(EPROPERTY_NUMBER_EXCEED_LIMIT));
self.map.add(key, value);
}

length

public fun length(self: &property_map::PropertyMap): u64
Implementation
public fun length(self: &PropertyMap): u64 {
self.map.length()
}

borrow

public fun borrow(self: &property_map::PropertyMap, key: &string::String): &property_map::PropertyValue
Implementation
public fun borrow(self: &PropertyMap, key: &String): &PropertyValue {
let found = self.contains_key(key);
assert!(found, EPROPERTY_NOT_EXIST);
self.map.borrow(key)
}

keys

Return all the keys in the property map in the order they are added.

public fun keys(self: &property_map::PropertyMap): vector<string::String>
Implementation
public fun keys(self: &PropertyMap): vector<String> {
self.map.keys()
}

types

Return the types of all properties in the property map in the order they are added.

public fun types(self: &property_map::PropertyMap): vector<string::String>
Implementation
public fun types(self: &PropertyMap): vector<String> {
self.map.values().map_ref(|v| {
v.type
})
}

values

Return the values of all properties in the property map in the order they are added.

public fun values(self: &property_map::PropertyMap): vector<vector<u8>>
Implementation
public fun values(self: &PropertyMap): vector<vector<u8>> {
self.map.values().map_ref(|v| {
v.value
})
}

read_string

public fun read_string(self: &property_map::PropertyMap, key: &string::String): string::String
Implementation
public fun read_string(self: &PropertyMap, key: &String): String {
let prop = self.borrow(key);
assert!(prop.type == string::utf8(b"0x1::string::String"), error::invalid_state(ETYPE_NOT_MATCH));
from_bcs::to_string(prop.value)
}

read_u8

public fun read_u8(self: &property_map::PropertyMap, key: &string::String): u8
Implementation
public fun read_u8(self: &PropertyMap, key: &String): u8 {
let prop = self.borrow(key);
assert!(prop.type == string::utf8(b"u8"), error::invalid_state(ETYPE_NOT_MATCH));
from_bcs::to_u8(prop.value)
}

read_u64

public fun read_u64(self: &property_map::PropertyMap, key: &string::String): u64
Implementation
public fun read_u64(self: &PropertyMap, key: &String): u64 {
let prop = self.borrow(key);
assert!(prop.type == string::utf8(b"u64"), error::invalid_state(ETYPE_NOT_MATCH));
from_bcs::to_u64(prop.value)
}

read_address

public fun read_address(self: &property_map::PropertyMap, key: &string::String): address
Implementation
public fun read_address(self: &PropertyMap, key: &String): address {
let prop = self.borrow(key);
assert!(prop.type == string::utf8(b"address"), error::invalid_state(ETYPE_NOT_MATCH));
from_bcs::to_address(prop.value)
}

read_u128

public fun read_u128(self: &property_map::PropertyMap, key: &string::String): u128
Implementation
public fun read_u128(self: &PropertyMap, key: &String): u128 {
let prop = self.borrow(key);
assert!(prop.type == string::utf8(b"u128"), error::invalid_state(ETYPE_NOT_MATCH));
from_bcs::to_u128(prop.value)
}

read_bool

public fun read_bool(self: &property_map::PropertyMap, key: &string::String): bool
Implementation
public fun read_bool(self: &PropertyMap, key: &String): bool {
let prop = self.borrow(key);
assert!(prop.type == string::utf8(b"bool"), error::invalid_state(ETYPE_NOT_MATCH));
from_bcs::to_bool(prop.value)
}

borrow_value

public fun borrow_value(self: &property_map::PropertyValue): vector<u8>
Implementation
public fun borrow_value(self: &PropertyValue): vector<u8> {
self.value
}

borrow_type

public fun borrow_type(self: &property_map::PropertyValue): string::String
Implementation
public fun borrow_type(self: &PropertyValue): String {
self.type
}

remove

public fun remove(self: &mut property_map::PropertyMap, key: &string::String): (string::String, property_map::PropertyValue)
Implementation
public fun remove(
self: &mut PropertyMap,
key: &String
): (String, PropertyValue) {
let found = self.contains_key(key);
assert!(found, error::not_found(EPROPERTY_NOT_EXIST));
self.map.remove(key)
}

update_property_map

Update the property in the existing property map Allow updating existing keys’ value and add new key-value pairs

public fun update_property_map(self: &mut property_map::PropertyMap, keys: vector<string::String>, values: vector<vector<u8>>, types: vector<string::String>)
Implementation
public fun update_property_map(
self: &mut PropertyMap,
keys: vector<String>,
values: vector<vector<u8>>,
types: vector<String>,
) {
let key_len = keys.length();
let val_len = values.length();
let typ_len = types.length();
assert!(key_len == val_len, error::invalid_state(EKEY_COUNT_NOT_MATCH_VALUE_COUNT));
assert!(key_len == typ_len, error::invalid_state(EKEY_COUNT_NOT_MATCH_TYPE_COUNT));
for (i in 0..key_len) {
let key = &keys[i];
let prop_val = PropertyValue {
value: values[i],
type: types[i],
};
if (self.contains_key(key)) {
self.update_property_value(key, prop_val);
} else {
self.add(*key, prop_val);
};
}
}

update_property_value

public fun update_property_value(self: &mut property_map::PropertyMap, key: &string::String, value: property_map::PropertyValue)
Implementation
public fun update_property_value(
self: &mut PropertyMap,
key: &String,
value: PropertyValue
) {
let property_val = self.map.borrow_mut(key);
*property_val = value;
}

create_property_value_raw

public fun create_property_value_raw(value: vector<u8>, type: string::String): property_map::PropertyValue
Implementation
public fun create_property_value_raw(
value: vector<u8>,
type: String
): PropertyValue {
PropertyValue {
value,
type,
}
}

create_property_value

create a property value from generic type data

public fun create_property_value<T: copy>(data: &T): property_map::PropertyValue
Implementation
public fun create_property_value<T: copy>(data: &T): PropertyValue {
let name = type_name<T>();
if (
name == string::utf8(b"bool") ||
name == string::utf8(b"u8") ||
name == string::utf8(b"u64") ||
name == string::utf8(b"u128") ||
name == string::utf8(b"address") ||
name == string::utf8(b"0x1::string::String")
) {
create_property_value_raw(bcs::to_bytes<T>(data), name)
} else {
create_property_value_raw(bcs::to_bytes<T>(data), string::utf8(b"vector<u8>"))
}
}

Specification

pragma verify = true;
pragma aborts_if_is_strict;
let MAX_PROPERTY_MAP_SIZE = 1000;
let MAX_PROPERTY_NAME_LENGTH = 128;

new

public fun new(keys: vector<string::String>, values: vector<vector<u8>>, types: vector<string::String>): property_map::PropertyMap
pragma aborts_if_is_partial;
let length = len(keys);
aborts_if !(length <= MAX_PROPERTY_MAP_SIZE);
aborts_if !(length == len(values));
aborts_if !(length == len(types));

new_with_key_and_property_value

public fun new_with_key_and_property_value(keys: vector<string::String>, values: vector<property_map::PropertyValue>): property_map::PropertyMap
pragma aborts_if_is_partial;
let length = len(keys);
aborts_if !(length <= MAX_PROPERTY_MAP_SIZE);
aborts_if !(length == len(values));

empty

public fun empty(): property_map::PropertyMap
aborts_if false;

contains_key

public fun contains_key(self: &property_map::PropertyMap, key: &string::String): bool
aborts_if false;

add

public fun add(self: &mut property_map::PropertyMap, key: string::String, value: property_map::PropertyValue)
aborts_if !(key.length() <= MAX_PROPERTY_NAME_LENGTH);
aborts_if !(!simple_map::spec_contains_key(self.map, key));
aborts_if !(simple_map::spec_len(self.map) < MAX_PROPERTY_MAP_SIZE);

length

public fun length(self: &property_map::PropertyMap): u64
aborts_if false;

borrow

public fun borrow(self: &property_map::PropertyMap, key: &string::String): &property_map::PropertyValue
aborts_if !simple_map::spec_contains_key(self.map, key);

keys

public fun keys(self: &property_map::PropertyMap): vector<string::String>
pragma verify = false;

types

public fun types(self: &property_map::PropertyMap): vector<string::String>
pragma verify = false;

values

public fun values(self: &property_map::PropertyMap): vector<vector<u8>>
pragma verify = false;

read_string

public fun read_string(self: &property_map::PropertyMap, key: &string::String): string::String

Check utf8 for correctness and whether equal to prop.type

pragma aborts_if_is_partial;
aborts_if !simple_map::spec_contains_key(self.map, key);
aborts_if !string::spec_internal_check_utf8(b"0x1::string::String");
let prop = simple_map::spec_get(self.map, key);
aborts_if prop.type != spec_utf8(b"0x1::string::String");
aborts_if !aptos_std::from_bcs::deserializable<String>(prop.value);
fun spec_utf8(bytes: vector<u8>): String {
String { bytes }
}

read_u8

public fun read_u8(self: &property_map::PropertyMap, key: &string::String): u8
let str = b"u8";
aborts_if !simple_map::spec_contains_key(self.map, key);
aborts_if !string::spec_internal_check_utf8(str);
let prop = simple_map::spec_get(self.map, key);
aborts_if prop.type != spec_utf8(str);
aborts_if !aptos_std::from_bcs::deserializable<u8>(prop.value);

read_u64

public fun read_u64(self: &property_map::PropertyMap, key: &string::String): u64
let str = b"u64";
aborts_if !simple_map::spec_contains_key(self.map, key);
aborts_if !string::spec_internal_check_utf8(str);
let prop = simple_map::spec_get(self.map, key);
aborts_if prop.type != spec_utf8(str);
aborts_if !aptos_std::from_bcs::deserializable<u64>(prop.value);

read_address

public fun read_address(self: &property_map::PropertyMap, key: &string::String): address
let str = b"address";
aborts_if !simple_map::spec_contains_key(self.map, key);
aborts_if !string::spec_internal_check_utf8(str);
let prop = simple_map::spec_get(self.map, key);
aborts_if prop.type != spec_utf8(str);
aborts_if !aptos_std::from_bcs::deserializable<address>(prop.value);

read_u128

public fun read_u128(self: &property_map::PropertyMap, key: &string::String): u128
let str = b"u128";
aborts_if !simple_map::spec_contains_key(self.map, key);
aborts_if !string::spec_internal_check_utf8(str);
let prop = simple_map::spec_get(self.map, key);
aborts_if prop.type != spec_utf8(str);
aborts_if !aptos_std::from_bcs::deserializable<u128>(prop.value);

read_bool

public fun read_bool(self: &property_map::PropertyMap, key: &string::String): bool
let str = b"bool";
aborts_if !simple_map::spec_contains_key(self.map, key);
aborts_if !string::spec_internal_check_utf8(str);
let prop = simple_map::spec_get(self.map, key);
aborts_if prop.type != spec_utf8(str);
aborts_if !aptos_std::from_bcs::deserializable<bool>(prop.value);

borrow_value

public fun borrow_value(self: &property_map::PropertyValue): vector<u8>
aborts_if false;

borrow_type

public fun borrow_type(self: &property_map::PropertyValue): string::String
aborts_if false;

remove

public fun remove(self: &mut property_map::PropertyMap, key: &string::String): (string::String, property_map::PropertyValue)
aborts_if !simple_map::spec_contains_key(self.map, key);

update_property_map

public fun update_property_map(self: &mut property_map::PropertyMap, keys: vector<string::String>, values: vector<vector<u8>>, types: vector<string::String>)
pragma aborts_if_is_partial;
let key_len = len(keys);
let val_len = len(values);
let typ_len = len(types);
aborts_if !(key_len == val_len);
aborts_if !(key_len == typ_len);

update_property_value

public fun update_property_value(self: &mut property_map::PropertyMap, key: &string::String, value: property_map::PropertyValue)
aborts_if !simple_map::spec_contains_key(self.map, key);

create_property_value_raw

public fun create_property_value_raw(value: vector<u8>, type: string::String): property_map::PropertyValue
aborts_if false;

create_property_value

public fun create_property_value<T: copy>(data: &T): property_map::PropertyValue

Abort according to the code

let name = type_name<T>();
aborts_if !string::spec_internal_check_utf8(b"bool");
aborts_if name != spec_utf8(b"bool") &&
!string::spec_internal_check_utf8(b"u8");
aborts_if name != spec_utf8(b"bool") &&
name != spec_utf8(b"u8") &&
!string::spec_internal_check_utf8(b"u64");
aborts_if name != spec_utf8(b"bool") &&
name != spec_utf8(b"u8") &&
name != spec_utf8(b"u64") &&
!string::spec_internal_check_utf8(b"u128");
aborts_if name != spec_utf8(b"bool") &&
name != spec_utf8(b"u8") &&
name != spec_utf8(b"u64") &&
name != spec_utf8(b"u128") &&
!string::spec_internal_check_utf8(b"address");
aborts_if name != spec_utf8(b"bool") &&
name != spec_utf8(b"u8") &&
name != spec_utf8(b"u64") &&
name != spec_utf8(b"u128") &&
name != spec_utf8(b"address") &&
!string::spec_internal_check_utf8(b"0x1::string::String");
aborts_if name != spec_utf8(b"bool") &&
name != spec_utf8(b"u8") &&
name != spec_utf8(b"u64") &&
name != spec_utf8(b"u128") &&
name != spec_utf8(b"address") &&
name != spec_utf8(b"0x1::string::String") &&
!string::spec_internal_check_utf8(b"vector<u8>");