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
//! BufReadSplitter can read a buffer, stopping before each separator encounter. This separator can be changed.
//!
//! Example :
//!
//! ```
//! use buf_read_splitter::buf_read_splitter::BufReadSplitter;
//! use std::io::Read;
//!
//! let input = "First<SEP><SEP>X<SEP>Second<SEP>Third<SEP>The last!".to_string();
//! let mut input_reader = input.as_bytes();
//! let mut reader = BufReadSplitter::new(10, &mut input_reader, "<SEP>".as_bytes());
//! let mut i = 0;
//! loop {
//! i += 1;
//!
//! let mut buf = [0u8; 3];
//! let mut text = String::new();
//!
//! loop {
//! let sz = reader.read(&mut buf).unwrap();
//! if sz > 0 {
//! let str = String::from_utf8_lossy(&buf[..sz]);
//! text.push_str(&str);
//! } else {
//! // End of buffer
//! match i {
//! 1 => {
//! assert_eq!(text, "First", "Case 1");
//! }
//! 2 => {
//! assert_eq!(text, "", "Case 2");
//! }
//! 3 => {
//! assert_eq!(text, "X", "Case 3");
//! }
//! 4 => {
//! assert_eq!(text, "Second", "Case 4");
//! }
//! 5 => {
//! assert_eq!(text, "Third", "Case 5");
//! }
//! 6 => {
//! assert_eq!(text, "The last!", "Case 10");
//! }
//! _ => {
//! assert_eq!(false, true, "Overflow")
//! }
//! }
//! break;
//! }
//! }
//!
//! match reader.next() {
//! Some(Ok(_)) => {}
//! Some(Err(err)) => panic!("Error : {err}"),
//! None => break,
//! }
//! }
//! ```
//!
//! Or example with changing separator :
//!
//! ```
//! use buf_read_splitter::buf_read_splitter::BufReadSplitter;
//! use std::io::Read;
//!
//! let input = "First<SEP><SEP>X<SEP>Second<SEP2>Y<SEP2>Small<>0<>Bigger<SEPARATOR_03>Till the end...<end>The last!".to_string();
//! // 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
//! // 10 20 30 40 50 60 70 80 90
//! let mut input_reader = input.as_bytes();
//! let mut reader = BufReadSplitter::new(20, &mut input_reader, "<SEP>".as_bytes());
//! let mut i = 0;
//! loop {
//! i += 1;
//!
//! let mut buf = [0u8; 3];
//! let mut text = String::new();
//!
//! loop {
//! let sz = reader.read(&mut buf).unwrap();
//! if sz > 0 {
//! let str = String::from_utf8_lossy(&buf[..sz]);
//! text.push_str(&str);
//! } else {
//! // End of buffer
//! match i {
//! 1 => {
//! assert_eq!(text, "First", "Case 1");
//! }
//! 2 => {
//! assert_eq!(text, "", "Case 2");
//! }
//! 3 => {
//! assert_eq!(text, "X", "Case 3");
//! }
//! 4 => {
//! assert_eq!(text, "Second", "Case 4");
//! }
//! 5 => {
//! assert_eq!(text, "Y", "Case 5");
//! }
//! 6 => {
//! assert_eq!(text, "Small", "Case 6");
//! }
//! 7 => {
//! assert_eq!(text, "0", "Case 7");
//! }
//! 8 => {
//! assert_eq!(text, "Bigger", "Case 8");
//! }
//! 9 => {
//! assert_eq!(text, "Till the end...", "Case 9");
//! }
//! 10 => {
//! assert_eq!(text, "The last!", "Case 10");
//! }
//! _ => {
//! assert_eq!(false, true, "Overflow")
//! }
//! }
//! break;
//! }
//! }
//!
//! match reader.next_split_on({
//! match i {
//! 3 => Some("<SEP2>".as_bytes()),
//! 5 => Some("<>".as_bytes()),
//! 7 => Some("<SEPARATOR_03>".as_bytes()),
//! 8 => Some("<end>".as_bytes()),
//! _ => None,
//! }
//! }) {
//! Some(Ok(_)) => {}
//! Some(Err(err)) => panic!("Error : {err}"),
//! None => break,
//! }
//! }
//!
//! assert_eq!(i, 10, "Not the count")
//! ```
//!
//! Its functions are not thread safe as-is, a Mutex has to be explicitly used.