For a list of documents, see: Rust Mobile Complex Graphics Rendering Project Development Series summary (table of Contents)

Rust string operation reference code

Both C/C++ char arrays and char * can be converted to Rust Byte strings, and then the operations provided by String can be used to quickly accomplish development requirements.

use std::str;

// This is "hello world" as an array of bytes.
// You can also start from a byte string b"hello world" and debug print that to get the
// utf8 encoded decimal values
println!("hello byte string: {:? }".b"hello world");

// OK so let's say you have an array of u8s
let array_of_u8 = [104.101.108.108.111.32.119.111.114.108.100];

// [u8] to String (lossy)
// Any invalid bytes that are not utf8 will be replaced with
// the unicode replacement character '\u{FFFD}'
// You get a Cow (Clone on Write) not exactly a String
let string_utf8_lossy = String::from_utf8_lossy(&array_of_u8);
println!("string_utf8_lossy: {}", string_utf8_lossy);

// [u8] to String (result)
// The non-lossy version needs a vec not an array
let mut vec_of_u8 = vec![];
vec_of_u8.extend_from_slice(&array_of_u8);
let string_utf8_result = String::from_utf8(vec_of_u8).unwrap();
println!("string_utf8_result: {}", string_utf8_result);

// [u8] to str (result)
let str_utf8_result = str::from_utf8(&array_of_u8).unwrap();
println!("str_utf8_result: {}", str_utf8_result);

// [u8] to str (lossy)
// There is no str::from_utf8_lossy. Have to use String::from_utf8_lossy

// [u8] to Vec<char>
let vec_of_chars: Vec<char> = array_of_u8.iter().map(|byte| *byte as char).collect();
println!("vec_of_chars: {:? }", vec_of_chars);

// Vec<char> to Vec<u8>
let vec_of_u8s: Vec<u8> = vec_of_chars.iter().map(|c| *c as u8).collect();
println!("vec_of_u8s: {:? }", vec_of_u8s);

// Vec<char> to String
let mut string_of_collected_chars: String = vec_of_chars.iter().collect();
println!("string_of_collected_chars: {}", string_of_collected_chars);

// Now we have a mutable String. We can push chars
string_of_collected_chars.push('! ');

// and we can push a str
string_of_collected_chars.push_str("!!!!!");

// String to str
let str_slice = &string_of_collected_chars[..5];
println!("str_slice: {}", &str_slice);

// String to [u8]
let array_of_u8_from_string = string_of_collected_chars.as_bytes();
println!("array_of_u8_from_string: {:? }", array_of_u8_from_string);

// String to Vec<char>
let vec_of_chars_to_string: Vec<char> = string_of_collected_chars.chars().collect();
println!("vec_of_chars: {:? }", vec_of_chars_to_string);

// String from several Strings
let concat_strings = vec!["abc".to_string(), "def".to_string()].concat();
println!("concat_strings: {}", concat_strings);
let joined_strings = vec!["abc".to_string(), "def".to_string()].join("-");
println!("joined_strings: {}", joined_strings);
Copy the code

String manipulation is implemented in C++ and Rust respectively

Convert C/C++ strings to Rust strings

Rust handling strings defined by C/C++ is a little more complicated. To reuse operations defined by Rust String as much as possible, you need to convert C/C++ strings from char [] or CHAR * to u8 arrays, and then to String, as shown in the following code:

// shader_u8_slice equals char[COUNT]
let shader_u8_slice = B "\ t# define \ tDITHERAMOUNT \ t0.5 \ n \ t# define \ tDITHERBIAS \ t0.5 \ n";
let shader_byte_string = {
    let mut shader_u8_vec = vec![];
    shader_u8_vec.extend_from_slice(shader_u8_slice);
    unsafe { String::from_utf8_unchecked(shader_u8_vec) };
};
println!("replaced shader_byte_string:\n{}", shader_byte_string);
Copy the code

Global replacement string

C++ replaces all from substrings in source with to substrings. Rust uses String::replace() as a single function.

void replace_all(string& source, const string& from, const string& to)
{
    auto pos = source.find(from);

    while(pos ! =string::npos) { source.replace(pos, from.size(), to); pos = source.find(from, pos + to.size()); }}Copy the code
// Heap allocate a string
let source = String::from("I like dogs");
// Allocate new memory and store the modified string there
let replaced_string: String = source.replace(from, to);
Copy the code

The previous C/C++ String can also be converted to Rust String by calling String::replace(), as shown in the following code:

let shader_u8_slice = B "\ t# define \ tDITHERAMOUNT \ t0.5 \ n \ t# define \ tDITHERBIAS \ t0.5 \ n";
let shader_byte_string = {
    let mut shader_u8_vec = vec![];
    shader_u8_vec.extend_from_slice(shader_u8_slice);
    let shader_byte_string = unsafe { String::from_utf8_unchecked(shader_u8_vec) };
    shader_byte_string.replace("\t"."")};println!("replaced shader_byte_string:\n{}", shader_byte_string);
Copy the code

Learning materials

  • peterlyons/rust converting bytes chars and strings
  • rust-by-example/string
  • servo/string-cache
  • carllerche/string Rust String type with configurable byte storage.
  • Zslayton/LifeGuard String_pool Reference example, inspired by the FrankMcSherry/Recycler project.
  • a-guide-to-porting-c-to-rust/strings
  • Crates. IO/crates/” gramm…
  • Crates. IO/crates/to_s…
  • Crates. IO/crates/comp…
  • Crates. IO/crates/byte…
  • Crates. IO/crates/byte…
  • Crates. IO/crates/stri…
  • Crates. IO/crates/lexi…
  • Crates. IO/crates/stri…
  • Crates. IO/crates/c_st…
  • crates.io/crates/nom
  • Github.com/phaazon/gls… Written based on nom
  • Crates. IO/crates/shad…