1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
//! `onigiri::tools` contains some tools of handling chars.
///
/// 2018 Nov 5, I add new function "search_all"
use std::str::FromStr;
use std::collections::BTreeMap;
pub fn chars_to_string(chars: &Vec<char>) -> String {
//! Convert from `Vec<char>` to `String`.
//! ```
//! let chars: Vec<char> = vec!['-', '1', '2', '3'];
//! assert_eq!(
//! onigiri::tools::chars_to_string(&chars),
//! "-123".to_string());
//! ```
let vec_str: Vec<String> = chars.iter()
.map(|ref v| v.to_string()).collect();
let result = vec_str.concat();
result
}
pub fn create_vvchar(text: &String) -> Vec<Vec<char>>{
//! This function convert from `String` to `Vec<Vec<char>>`.
//! ```
//! let text = "123 456".to_string();
//! assert_eq!(
//! onigiri::tools::create_vvchar(&text),
//! vec![vec!['1','2','3'], vec!['4','5','6']]
//! );
//! ```
let split_text: Vec<&str> = text.split_whitespace().collect();
let vvchar: Vec<Vec<char>> = split_text.iter()
.map(|&x| x.chars().collect()).collect();
vvchar
}
// Vvc is abbreviation of Vec<Vec<char>>.
#[derive(Debug, PartialEq, Clone)]
pub struct Vvc {
pub attr: Vec<Vec<char>>,
count: usize
}
impl Vvc {
pub fn new(attr: &String) -> Vvc {
//! This function create `Vvc` from `String`.
//! It is almost the same as `create_vvchar()`,
//! but you can use `next()` and `nth()`.
//!
//! ```
//! let test_text = "-123".to_string();
//! let mut new_vvc = onigiri::tools::Vvc::new(&test_text);
//! assert_eq!(&new_vvc.attr, &vec![vec!['-','1','2','3']]);
//! ```
Vvc { attr: create_vvchar(&attr), count: 0 }
}
// TODO: I think this function is useful.
// But this one may be wasteful.
pub fn create_btm(self) -> Option<BTreeMap<usize, Vec<char>>> {
//! This function is create BTreeMap of `Vec<char>`.
//! Perhaps, this one may be more convenient.
//! ```
//! let test_text = "-123 456".to_string();
//! let mut new_vvc = onigiri::tools::Vvc::new(&test_text);
//! let btm = &new_vvc.create_btm().unwrap();
//! assert_eq!(
//! btm.get(&0).unwrap(),
//! &vec!['-', '1', '2', '3']
//! );
//! assert_eq!(
//! btm.get(&1).unwrap(),
//! &vec!['4', '5', '6']
//! );
//! ```
let mut bt = BTreeMap::new();
for (k, v) in self.attr.into_iter().enumerate() {
bt.insert(k,v);
}
if bt.is_empty() {
None
} else { Some(bt) }
}
pub fn search_all(self, word: String) -> Option<Vec<usize>> {
//! This function can search a word. And return index.
//! ```
//! extern crate onigiri;
//! use onigiri::tools::Vvc;
//! let result = Vvc::search_all(
//! Vvc::new(&"Hello world Hello".to_string()),
//! "Hello".to_string()
//! );
//! assert_eq!(result, Some(vec![0, 2]));
//! ```
let base_btm = &self.create_btm().unwrap();
let word_vc: Vec<char> = word.chars().collect();
let mut stack: Vec<usize> = vec![];
for k in 0..base_btm.len() {
if base_btm.get(&k).unwrap() == &word_vc {
stack.push(k);
} else { continue; }
}
match stack.len() {
0 => None,
_ => Some(stack)
}
}
}
// This iterator iterates over Vec<Vec<char>> converted to String.
impl Iterator for Vvc {
type Item = String;
fn next(&mut self) -> Option<Self::Item> {
//! ```
//! let test_text = "-123 + 456".to_string();
//! let mut new_vvc = onigiri::tools::Vvc::new(&test_text);
//! assert_eq!(new_vvc.next(), Some("-123".to_string()));
//! assert_eq!(new_vvc.next(), Some("+".to_string()));
//! assert_eq!(new_vvc.next(), Some("456".to_string()));
//! assert_eq!(new_vvc.next(), None);
//! ```
self.count += 1;
if self.count <= self.attr.len() {
Some(chars_to_string(&(self.attr[self.count - 1])))
} else {
None
}
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
//! ```
//! let test_text = "-123 + 456".to_string();
//! let mut new_vvc = onigiri::tools::Vvc::new(&test_text);
//! assert_eq!(new_vvc.nth(1), Some("+".to_string()));
//! assert_eq!(new_vvc.nth(3), None);
//! ```
if n < self.attr.len() {
Some(chars_to_string(&(self.attr[n])))
} else {
None
}
}
}
pub fn cast<T: FromStr>(vc: &Vec<char>) -> Option<T> {
//! This function can cast from `Vec<char>` to some types.
//! ```
//! let test_vc = vec!['-','1','2'];
//! assert_eq!(
//! onigiri::tools::cast::<i32>(&test_vc),
//! Some(-12_i32)
//! );
//! ```
let vc2s = chars_to_string(&vc);
match T::from_str(&vc2s) {
Ok(n) => Some(n),
_ => None
}
}