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
    }
}