# 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.
- [Struct `String`](#0x1_ascii_String)
- [Struct `Char`](#0x1_ascii_Char)
- [Constants](#@Constants_0)
- [Function `char`](#0x1_ascii_char)
- [Function `string`](#0x1_ascii_string)
- [Function `try_string`](#0x1_ascii_try_string)
- [Function `all_characters_printable`](#0x1_ascii_all_characters_printable)
- [Function `push_char`](#0x1_ascii_push_char)
- [Function `pop_char`](#0x1_ascii_pop_char)
- [Function `length`](#0x1_ascii_length)
- [Function `as_bytes`](#0x1_ascii_as_bytes)
- [Function `into_bytes`](#0x1_ascii_into_bytes)
- [Function `byte`](#0x1_ascii_byte)
- [Function `is_valid_char`](#0x1_ascii_is_valid_char)
- [Function `is_printable_char`](#0x1_ascii_is_printable_char)
use 0x1::option;
## 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>
-
Specification
invariant forall i in 0..len(bytes): is_valid_char(bytes[i]);
## Struct `Char`
An ASCII character.
struct Char has copy, drop, store
Fields
-
byte: u8
-
Specification
invariant is_valid_char(byte);
## Constants
An invalid ASCII character was encountered when creating an ASCII string.
const EINVALID_ASCII_CHARACTER: u64 = 65536;
## 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), EINVALID_ASCII_CHARACTER);
Char { byte }
}
Specification
aborts_if !is_valid_char(byte) with EINVALID_ASCII_CHARACTER;
## 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!(
option::is_some(&x),
EINVALID_ASCII_CHARACTER
);
option::destroy_some(x)
}
Specification
aborts_if exists i in 0..len(bytes): !is_valid_char(bytes[i]) with EINVALID_ASCII_CHARACTER;
## 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 = vector::length(&bytes);
let i = 0;
while ({
spec {
invariant i <= len;
invariant forall j in 0..i: is_valid_char(bytes[j]);
};
i < len
}) {
let possible_byte = *vector::borrow(&bytes, i);
if (!is_valid_char(possible_byte)) return option::none();
i = i + 1;
};
spec {
assert i == len;
assert forall j in 0..len: is_valid_char(bytes[j]);
};
option::some(String { bytes })
}
## Function `all_characters_printable`
Returns true
if all characters in string
are printable characters
Returns false
otherwise. Not all String
s are printable strings.
public fun all_characters_printable(string: &ascii::String): bool
Implementation
public fun all_characters_printable(string: &String): bool {
let len = vector::length(&string.bytes);
let i = 0;
while ({
spec {
invariant i <= len;
invariant forall j in 0..i: is_printable_char(string.bytes[j]);
};
i < len
}) {
let byte = *vector::borrow(&string.bytes, i);
if (!is_printable_char(byte)) return false;
i = i + 1;
};
spec {
assert i == len;
assert forall j in 0..len: is_printable_char(string.bytes[j]);
};
true
}
Specification
ensures result ==> (forall j in 0..len(string.bytes): is_printable_char(string.bytes[j]));
## Function `push_char`
public fun push_char(string: &mut ascii::String, char: ascii::Char)
Implementation
public fun push_char(string: &mut String, char: Char) {
vector::push_back(&mut string.bytes, char.byte);
}
Specification
ensures len(string.bytes) == len(old(string.bytes)) + 1;
## Function `pop_char`
public fun pop_char(string: &mut ascii::String): ascii::Char
Implementation
public fun pop_char(string: &mut String): Char {
Char { byte: vector::pop_back(&mut string.bytes) }
}
Specification
ensures len(string.bytes) == len(old(string.bytes)) - 1;
## Function `length`
public fun length(string: &ascii::String): u64
Implementation
public fun length(string: &String): u64 {
vector::length(as_bytes(string))
}
## 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 byte.
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
}
[//]: # ("File containing references which can be used from documentation")