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}