-
Notifications
You must be signed in to change notification settings - Fork 2
/
replace.rs
86 lines (76 loc) · 2.33 KB
/
replace.rs
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
use anyhow::Result;
use std::io::Write;
pub struct Replacement {
pub start: usize,
pub end: usize,
pub text: String,
}
impl Replacement {
pub fn new(start: usize, end: usize, text: impl Into<String>) -> Replacement {
let text = text.into();
Replacement { start, end, text }
}
}
pub fn replace_all<W: Write>(mut out: W, input: &str, replacements: &[Replacement]) -> Result<()> {
let mut i = 0;
for replacement in replacements.iter() {
let Replacement { start, end, text } = replacement;
out.write_all(input[i..*start].as_bytes())?;
out.write_all(text.as_bytes())?;
i = *end;
}
out.write_all(input[i..].as_bytes())?;
Ok(out.flush()?)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::test_helper::*;
use std::array::IntoIter;
use std::str;
#[test]
fn replace_one() {
let mut buf = Vec::new();
let rep = &[Replacement::new(4, 4 + "hello".len(), "goodbye")];
replace_all(&mut buf, "hi! hello world!", rep).unwrap();
let o = str::from_utf8(&buf).unwrap();
assert_eq!(o, "hi! goodbye world!");
}
#[test]
fn replace_multiple() {
let mut buf = Vec::new();
let rep = &[
Replacement::new(0, "hi!".len(), "woo!"),
Replacement::new(4, 4 + "hello".len(), "goodbye"),
Replacement::new(10, 10 + "world".len(), "universe"),
];
replace_all(&mut buf, "hi! hello world!", rep).unwrap();
let o = str::from_utf8(&buf).unwrap();
assert_eq!(o, "woo! goodbye universe!");
}
#[test]
fn replace_entire() {
let mut buf = Vec::new();
let rep = &[Replacement::new(0, "hello".len(), "goodbye")];
replace_all(&mut buf, "hello", rep).unwrap();
let o = str::from_utf8(&buf).unwrap();
assert_eq!(o, "goodbye");
}
#[test]
fn no_replacement() {
for i in IntoIter::new(["", "foo"]) {
let mut buf = Vec::new();
replace_all(&mut buf, i, &[]).unwrap();
let o = str::from_utf8(&buf).unwrap();
assert_eq!(i, o);
}
}
#[test]
fn write_error() {
assert!(replace_all(WriteErrorWriter, "foo", &[]).is_err());
}
#[test]
fn flush_error() {
assert!(replace_all(FlushErrorWriter, "foo", &[]).is_err());
}
}