#*
ABOUT
Just has some examples of rust syntax to help with writing the translator
RUST SYNTAX
* a technique to get out of immutable borrowing problems
>> self.matchClass(&self.work.clone(), etc);
>> ie use .clone()
* A gotcha is std::mem::swap has 2 forms &str and String and it
works out which variant from the first parameter.
* write to stdout with lock
----
let mut stdout = std::io::stdout().lock();
for i in 0..1000 {
writeln!(stdout, "{i}").unwrap();
}
,,,,
* write to file with the write macro
-----
fn main() -> std::io::Result<()> {
let path = "results.txt";
let mut output = File::create(path)?;
let line = "hello";
write!(output, "{}", line)
}
,,,,,
* check if any element of vector is "-i"
------
let n= vec!["-i","mmmm"];
if n.iter().any(|&i| i=="-i") {
println!("Yes");
}
,,,,
* search for pattern
------
use regex::Regex;
let re = Regex::new(r"\d+").unwrap(); // Matches one or more digits
let text = "The number is 123";
if re.is_match(text) {
println!("Regex match found!");
}
,,,,
* more unwrapping
----
let file_stem = match source_path.file_stem() {
Some(x) => x,
None => continue,
};
,,,,
* collect graphemes into vector and reverse
------
unicode-segmentation
input.graphemes(true).rev().collect()
,,,,,
* handling io errors in rust
-------
fn main() {
let greeting_file_result = File::open("hello.txt");
let greeting_file = match greeting_file_result {
Ok(file) => file,
Err(error) => match error.kind() {
ErrorKind::NotFound => match File::create("hello.txt") {
Ok(fc) => fc,
Err(e) => panic!("Problem creating the file: {e:?}"),
},
other_error => {
panic!("Problem opening the file: {other_error:?}");
}
},
};
}
,,,,
* read a reader into a string
------
fn main() -> io::Result<()> {
let stdin = io::read_to_string(io::stdin())?;
println!("Stdin was:");
println!("{stdin}");
Ok(())
}
,,,,
The code below unwraps the optional that is returned by the iterator.
* another way to use iterators, consuming each element
-------
let iter = vec.iter(); // vec is &Vec, not mutable
let mut str = String::new();
str.push_str("[");
while let Some(v) = iter.next() {
str.push_str(&v.str());
str.push_str(", ");
}
str.push_str("]");
,,,,
* you cant do this, ie chain methods in some cases.
>> self.work.clear().push_str(&s); //error
* remove first and last chars from string. handles unicode not graphemes
-------
fn rem_first_and_last(value: &str) -> &str {
let mut chars = value.chars();
chars.next();
chars.next_back();
chars.as_str()
}
,,,,
Iterate over graphemes.
----
use unicode_segmentation::UnicodeSegmentation;
for grapheme in my_str.graphemes(true) {
// ...
}
,,,
* need to use this for string vectors & converts to &str
>> let inputString = &args[pos+1];
braces are obligatory. If brackets are not.
* get command line args into a vector
------
use std::env;
fn main() {
let args: Vec<String> = env::args().collect();
dbg!(args);
}
,,,,
* print the last element of a vector.
----
fn main() {
let v = vec![1.0, 1.9, 1.2];
if let Some(val) = v.last() {
println!("Last element is {}", val);
} else {
println!("The vector is empty");
}
}
,,,,
* update first element of mutable vector
---
vec[0].some_value += 1;
vec.first_mut().unwrap().some_value += 1;
,,,
* iterate over vector with mutable reference (change element
----
let mut v = vec![100, 32, 57];
for i in &mut v {
*i += 50;
}
,,,,
* split string and iterate or collect
-----
let parts = "some string 123 content".split("123");
for part in parts {
println!("{}", part)
}
//Or:
let collection = parts.collect::<Vec<&str>>();
dbg!(collection);
,,,,
unicode_segmentation crate has .graphemes(true) conversion.
* iterate over graphemes, yes
-----
use unicode_segmentation::UnicodeSegmentation; // 1.5.0
fn main() {
for g in "नमसà¥à¤¤à¥‡".graphemes(true) {
println!("- {}", g);
}
}
,,,,
* read a line from stdin or a file
-----
let stdin = io::stdin();
for line in BufReader::new(stdin).lines() {
//the same way that one does:
let f = File::open(file)?;
for line in BufReader::new(f).lines() {
,,,,
adding a crate for utf8 parsing.
* Add the following to your Cargo.toml:
----
[dependencies]
utf8-chars = "1.0.0"
,,,,
// read from stdin or from a file or a string.
-----
BufReader::new(io::stdin())
BufReader::new(fs::File::open(filename).unwrap())
let mut streader = StringReader::new("Line 1\\nLine 2");
let mut bufreader = BufReader::new(streader);
,,,
* read char by char
----
let mut f = io::BufReader::new(try!(fs::File::open("input.txt")));
for c in f.chars() {
println!("Character: {}", c.unwrap());
}
,,,,
Rust string docs which are important for pep/nom
https://doc.rust-lang.org/std/string/struct.String.html#method.trim_end
Rust says that its string handling is bi-direction aware.
Rust has labelled loops
* rust for loop
------
let mut sum = 0;
for n in 1..11 {
sum += n;
}
assert_eq!(sum, 55);
,,,,
* define a string
>> let s = String::from("hello");
* define a vector of unicode chars (4 bytes each)
>> let v = vec!['h', 'e', 'l', 'l', 'o'];
But rust chars dont include unicode grapheme clusters (which
are sequences of chars)
* chain methods together
-----
let s = " English ";
assert!(Some('h') == s.trim_end().chars().rev().next());
,,,,
* trim whitespace from the end of a string
-----
let s = "\n Hello\tworld\t\n";
assert_eq!("\n Hello\tworld", s.trim_end());
,,,
* create a mutable string and add (unicode) char and string
----
let mut hello = String::from("Hello, ");
hello.push('w');
hello.push_str("orld!");
,,,,
* get the 3rd char, but not grapheme cluster.
---
let s = "hello";
let third_character = s.chars().nth(2);
assert_eq!(third_character, Some('l'));
,,,,
Rust strings are utf8 encoded but chars are 4 bytes.
* sparkle heart char
------
let s = "💖💖💖💖💖";
assert_eq!(s.len(), 20);
,,,,