wormhole/aptos/nft_bridge/sources/wrapped_token_name.move

78 lines
2.0 KiB
Plaintext

module nft_bridge::wrapped_token_name {
use std::vector;
use std::string::{Self, String};
const E_INVALID_HEX_DIGIT: u64 = 0;
const E_INVALID_HEX_CHAR: u64 = 1;
// TODO(csongor): rename this functions maybe
/// Render a vector as a hex string
public fun render_hex(bytes: vector<u8>): String {
let res = vector::empty<u8>();
vector::reverse(&mut bytes);
while (!vector::is_empty(&bytes)) {
let b = vector::pop_back(&mut bytes);
let l = b >> 4;
let h = b & 0xF;
vector::push_back(&mut res, hex_digit(l));
vector::push_back(&mut res, hex_digit(h));
};
string::utf8(res)
}
/// Returns the ASCII code for a hex digit (i.e. 0 -> '0', a -> 'a')
fun hex_digit(d: u8): u8 {
assert!(d < 16, E_INVALID_HEX_DIGIT);
if (d < 10) {
d + 48
} else {
d + 87
}
}
public fun parse_hex(s: String): vector<u8> {
let res = vector::empty<u8>();
let bytes = *string::bytes(&s);
while (!vector::is_empty(&bytes)) {
let h = hex_char(vector::pop_back(&mut bytes));
let l = hex_char(vector::pop_back(&mut bytes));
let b = (l << 4) + h;
vector::push_back(&mut res, b);
};
vector::reverse(&mut res);
res
}
// Inverse of hex_digit
fun hex_char(v: u8): u8 {
if (48 <= v && v <= 57) {
v - 48
} else if (97 <= v && v <= 102) {
v - 87
} else {
assert!(false, E_INVALID_HEX_CHAR);
0
}
}
}
#[test_only]
module nft_bridge::wrapped_token_name_test {
use std::string;
use nft_bridge::wrapped_token_name;
#[test]
fun render_hex_test() {
assert!(wrapped_token_name::render_hex(x"beefcafe") == string::utf8(b"beefcafe"), 0);
}
#[test]
fun parse_hex_test() {
assert!(wrapped_token_name::parse_hex(string::utf8(b"beefcafe")) == x"beefcafe", 0);
}
}