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
use crate::account_config::constants::CORE_CODE_ADDRESS;
use anyhow::{bail, ensure, Result};
use move_core_types::{
identifier::{IdentStr, Identifier},
language_storage::{ModuleId, StructTag, TypeTag},
};
use once_cell::sync::Lazy;
pub use move_core_types::vm_status::known_locations::{DIEM_MODULE, DIEM_MODULE_IDENTIFIER};
const COIN_MODULE_IDENTIFIER: &IdentStr = DIEM_MODULE_IDENTIFIER;
pub static COIN_MODULE: Lazy<ModuleId> =
Lazy::new(|| ModuleId::new(CORE_CODE_ADDRESS, COIN_MODULE_IDENTIFIER.to_owned()));
pub fn type_tag_for_currency_code(currency_code: Identifier) -> TypeTag {
TypeTag::Struct(StructTag {
address: CORE_CODE_ADDRESS,
module: currency_code.clone(),
name: currency_code,
type_params: vec![],
})
}
pub fn currency_code_from_type_tag(type_tag: TypeTag) -> Result<Identifier> {
let struct_tag = match type_tag {
TypeTag::Struct(struct_tag) => struct_tag,
_ => bail!(
"expected a type for a currency struct, received: {:?}",
type_tag
),
};
ensure!(
struct_tag.address == CORE_CODE_ADDRESS
&& struct_tag.module == struct_tag.name
&& struct_tag.type_params.is_empty(),
"not a valid currency struct tag: {:?}",
struct_tag,
);
let currency_code = struct_tag.name;
ensure!(
allowed_currency_code_string(currency_code.as_str()),
"currency code can only contain uppercase alphanumeric characters: '{}'",
currency_code,
);
Ok(currency_code)
}
pub fn allowed_currency_code_string(possible_currency_code_string: &str) -> bool {
possible_currency_code_string
.chars()
.all(|chr| matches!(chr, 'A'..='Z' | '0'..='9'))
&& Identifier::is_valid(possible_currency_code_string)
}
pub fn from_currency_code_string(currency_code_string: &str) -> Result<Identifier> {
if !allowed_currency_code_string(currency_code_string) {
bail!("Invalid currency code '{}'", currency_code_string)
}
Identifier::new(currency_code_string)
}