bitr/
utils.rs

1use std::str::FromStr;
2
3pub fn str_to_bool(value: &str) -> Result<bool, String> {
4    match value.trim() {
5        "0" => Ok(false),
6        "1" => Ok(true),
7        _ => Err(format!("unable to convert `{value}` into a binary value")),
8    }
9}
10
11pub fn char_to_bool(value: char) -> Result<bool, String> {
12    match value {
13        '0' => Ok(false),
14        '1' => Ok(true),
15        _ => Err(format!("unable to convert `{value}` into a binary value")),
16    }
17}
18
19pub fn str_to_bools(value: &str) -> Result<Vec<bool>, String> {
20    let mut bools = Vec::with_capacity(value.len());
21
22    for c in value.chars() {
23        bools.push(char_to_bool(c)?);
24    }
25
26    Ok(bools)
27}
28
29pub fn bools_to_string(values: &[bool]) -> String {
30    values
31        .iter()
32        .map(|&b| (b as u8).to_string())
33        .collect::<String>()
34}
35
36pub fn char_to_radix(c: char) -> Result<u32, String> {
37    match c.to_ascii_lowercase() {
38        'o' => Ok(8),
39        'h' => Ok(16),
40        'd' => Ok(10),
41        'b' => Ok(2),
42        _ => Err(format!("invalid radix `{c}`")),
43    }
44}
45
46pub fn parse_n<T>(s: &str) -> Result<T, String>
47where
48    T: FromStr,
49{
50    match s.parse::<T>() {
51        Ok(n) => Ok(n),
52        Err(_e) => Err(format!("cannot parse `{s} as usize`")),
53    }
54}
55
56pub fn find_brackets(
57    opening: char,
58    closing: char,
59    chars: &[char],
60) -> Result<Option<BracketInfo>, String> {
61    if chars.iter().filter(|c| **c == opening).count()
62        != chars.iter().filter(|c| **c == closing).count()
63    {
64        return Err(format!("mismatch amound of `{opening}` and `{closing}`"));
65    }
66
67    let bracket_end = match chars.iter().enumerate().find(|(_index, c)| **c == closing) {
68        Some((index, _c)) => index,
69        None => return Ok(None),
70    };
71
72    let bracket_begin = match chars
73        .iter()
74        .enumerate()
75        .rev()
76        .skip(chars.len() - bracket_end)
77        .find(|(_index, c)| **c == opening)
78    {
79        Some((index, _c)) => index,
80        None => return Err(String::from("mismatch brackets")),
81    };
82
83    let operator_begin = match chars
84        .iter()
85        .enumerate()
86        .take(bracket_begin)
87        .rev()
88        .find(|(_index, c)| !(c.is_ascii_alphabetic() || **c == '_'))
89    {
90        Some((index, _c)) => index + 1,
91        None => 0,
92    };
93
94    let operator = chars[operator_begin..bracket_begin]
95        .iter()
96        .collect::<String>();
97
98    let operands = chars[bracket_begin + 1..bracket_end]
99        .iter()
100        .collect::<String>();
101
102    Ok(Some(BracketInfo {
103        begin: operator_begin,
104        end: bracket_end,
105        name: operator,
106        content: operands,
107    }))
108}
109
110#[derive(Debug)]
111pub struct BracketInfo {
112    pub begin: usize,
113    pub end: usize,
114    pub name: String,
115    pub content: String,
116}
117
118pub fn escape(s: &mut String) {
119    *s = s.replace("\\n", "\n");
120}
121
122pub fn to_denary(bools: &[bool]) -> u64 {
123    bools
124        .iter()
125        .rev()
126        .enumerate()
127        .map(|(index, &b)| if b { 2_u64.pow(index as u32) } else { 0 })
128        .sum()
129}