Skip to main content

Module 0x1::ascii

The ASCII module defines basic string and char newtypes in Move that verify that characters are valid ASCII, and that strings consist of only valid ASCII characters.

use 0x1::option;
use 0x1::vector;

Struct String

The String struct holds a vector of bytes that all represent valid ASCII characters. Note that these ASCII characters may not all be printable. To determine if a String contains only "printable" characters you should use the all_characters_printable predicate defined in this module.

struct String has copy, drop, store
Fields
bytes: vector<u8>

Struct Char

An ASCII character.

struct Char has copy, drop, store
Fields
byte: u8

Constants

An invalid ASCII character was encountered when creating an ASCII string.

const EInvalidASCIICharacter: u64 = 65536;

An invalid index was encountered when creating a substring.

const EInvalidIndex: u64 = 65537;

Function char

Convert a byte into a Char that is checked to make sure it is valid ASCII.

public fun char(byte: u8): ascii::Char
Implementation
public fun char(byte: u8): Char {
    assert!(is_valid_char(byte), EInvalidASCIICharacter);
    Char { byte }
}

Function string

Convert a vector of bytes bytes into an String. Aborts if bytes contains non-ASCII characters.

public fun string(bytes: vector<u8>): ascii::String
Implementation
public fun string(bytes: vector<u8>): String {
   let x = try_string(bytes);
   assert!(x.is_some(), EInvalidASCIICharacter);
   x.destroy_some()
}

Function try_string

Convert a vector of bytes bytes into an String. Returns Some(<ascii_string>) if the bytes contains all valid ASCII characters. Otherwise returns None.

public fun try_string(bytes: vector<u8>): option::Option<ascii::String>
Implementation
public fun try_string(bytes: vector<u8>): Option<String> {
    let len = bytes.length();
    let mut i = 0;
    while (i < len) {
        let possible_byte = bytes[i];
        if (!is_valid_char(possible_byte)) return option::none();
        i = i + 1;
    };
    option::some(String { bytes })
}

Function all_characters_printable

Returns true if all characters in string are printable characters Returns false otherwise. Not all Strings are printable strings.

public fun all_characters_printable(string: &ascii::String): bool
Implementation
public fun all_characters_printable(string: &String): bool {
    let len = string.bytes.length();
    let mut i = 0;
    while (i < len) {
        let byte = string.bytes[i];
        if (!is_printable_char(byte)) return false;
        i = i + 1;
    };
    true
}

Function push_char

Push a Char to the end of the string.

public fun push_char(string: &mut ascii::String, char: ascii::Char)
Implementation
public fun push_char(string: &mut String, char: Char) {
    string.bytes.push_back(char.byte);
}

Function pop_char

Pop a Char from the end of the string.

public fun pop_char(string: &mut ascii::String): ascii::Char
Implementation
public fun pop_char(string: &mut String): Char {
    Char { byte: string.bytes.pop_back() }
}

Function length

Returns the length of the string in bytes.

public fun length(string: &ascii::String): u64
Implementation
public fun length(string: &String): u64 {
    string.as_bytes().length()
}

Function append

Append the other string to the end of string.

public fun append(string: &mut ascii::String, other: ascii::String)
Implementation
public fun append(string: &mut String, other: String) {
    string.bytes.append(other.into_bytes())
}

Function insert

Insert the other string at the at index of string.

public fun insert(s: &mut ascii::String, at: u64, o: ascii::String)
Implementation
public fun insert(s: &mut String, at: u64, o: String) {
    assert!(at <= s.length(), EInvalidIndex);
    let mut bytes = o.into_bytes();
    while (!bytes.is_empty()) {
        s.bytes.insert(bytes.pop_back(), at);
    };
}

Function substring

Copy the slice of the string from i to j into a new String.

public fun substring(string: &ascii::String, i: u64, j: u64): ascii::String
Implementation
public fun substring(string: &String, mut i: u64, j: u64): String {
    assert!(i <= j && j <= string.length(), EInvalidIndex);
    let mut bytes = vector[];
    while (i < j) {
        bytes.push_back(string.bytes[i]);
        i = i + 1;
    };
    String { bytes }
}

Function as_bytes

Get the inner bytes of the string as a reference

public fun as_bytes(string: &ascii::String): &vector<u8>
Implementation
public fun as_bytes(string: &String): &vector<u8> {
   &string.bytes
}

Function into_bytes

Unpack the string to get its backing bytes

public fun into_bytes(string: ascii::String): vector<u8>
Implementation
public fun into_bytes(string: String): vector<u8> {
   let String { bytes } = string;
   bytes
}

Function byte

Unpack the char into its underlying bytes.

public fun byte(char: ascii::Char): u8
Implementation
public fun byte(char: Char): u8 {
   let Char { byte } = char;
   byte
}

Function is_valid_char

Returns true if b is a valid ASCII character. Returns false otherwise.

public fun is_valid_char(b: u8): bool
Implementation
public fun is_valid_char(b: u8): bool {
   b <= 0x7F
}

Function is_printable_char

Returns true if byte is an printable ASCII character. Returns false otherwise.

public fun is_printable_char(byte: u8): bool
Implementation
public fun is_printable_char(byte: u8): bool {
   byte >= 0x20 && // Disallow metacharacters
   byte <= 0x7E // Don't allow DEL metacharacter
}

Function is_empty

Returns true if string is empty.

public fun is_empty(string: &ascii::String): bool
Implementation
public fun is_empty(string: &String): bool {
    string.bytes.is_empty()
}

Function to_uppercase

Convert a string to its uppercase equivalent.

public fun to_uppercase(string: &ascii::String): ascii::String
Implementation
public fun to_uppercase(string: &String): String {
    let (mut i, mut bytes) = (0, vector[]);
    while (i < string.length()) {
        bytes.push_back(char_to_uppercase(string.bytes[i]));
        i = i + 1;
    };
    String { bytes }
}

Function to_lowercase

Convert a string to its lowercase equivalent.

public fun to_lowercase(string: &ascii::String): ascii::String
Implementation
public fun to_lowercase(string: &String): String {
    let (mut i, mut bytes) = (0, vector[]);
    while (i < string.length()) {
        bytes.push_back(char_to_lowercase(string.bytes[i]));
        i = i + 1;
    };
    String { bytes }
}

Function index_of

Computes the index of the first occurrence of the substr in the string. Returns the length of the string if the substr is not found. Returns 0 if the substr is empty.

public fun index_of(string: &ascii::String, substr: &ascii::String): u64
Implementation
public fun index_of(string: &String, substr: &String): u64 {
    let mut i = 0;
    let (n, m) = (string.length(), substr.length());
    if (n < m) return n;
    while (i <= n - m) {
        let mut j = 0;
        while (j < m && string.bytes[i + j] == substr.bytes[j]) j = j + 1;
        if (j == m) return i;
        i = i + 1;
    };
    n
}

Function char_to_uppercase

Convert a char to its lowercase equivalent.

fun char_to_uppercase(byte: u8): u8
Implementation
fun char_to_uppercase(byte: u8): u8 {
    if (byte >= 0x61 && byte <= 0x7A) {
        byte - 0x20
    } else {
        byte
    }
}

Function char_to_lowercase

Convert a char to its lowercase equivalent.

fun char_to_lowercase(byte: u8): u8
Implementation
fun char_to_lowercase(byte: u8): u8 {
    if (byte >= 0x41 && byte <= 0x5A) {
        byte + 0x20
    } else {
        byte
    }
}