use crate::{Editor, NewlineType};
#[inline]
pub fn appender(text: &str, newlines: u8) -> Editor {
Factory::build(text, newlines, EditType::Append, NewlineType::Lf)
}
#[inline]
pub fn inserter(text: &str, newlines: u8) -> Editor {
Factory::build(text, newlines, EditType::Insert, NewlineType::Lf)
}
#[inline]
pub fn replacer(text: &str, newlines: u8) -> Editor {
Factory::build(text, newlines, EditType::Replace, NewlineType::Lf)
}
#[inline]
pub fn appender_crlf(text: &str, newlines: u8) -> Editor {
Factory::build(text, newlines, EditType::Append, NewlineType::Crlf)
}
#[inline]
pub fn inserter_crlf(text: &str, newlines: u8) -> Editor {
Factory::build(text, newlines, EditType::Insert, NewlineType::Crlf)
}
#[inline]
pub fn replacer_crlf(text: &str, newlines: u8) -> Editor {
Factory::build(text, newlines, EditType::Replace, NewlineType::Crlf)
}
#[derive(Debug)]
struct Factory<'a> {
text: &'a str,
edit_type: EditType,
newline: NewlineType,
trigger: u8,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
enum EditType {
Append,
Insert,
Replace,
}
impl<'a> Factory<'a> {
#[inline]
fn build(text: &'a str, trigger: u8, edit_type: EditType, newline: NewlineType) -> Editor {
let factory = Self {
text,
trigger,
edit_type,
newline,
};
factory.create_editor()
}
#[inline]
fn create_editor(&self) -> Editor {
let replace = match self.edit_type {
EditType::Append => self.append_string(),
EditType::Insert => self.insert_string(),
EditType::Replace => String::from(self.text),
};
Editor::new(replace, self.trigger, self.newline)
}
#[inline]
fn append_string(&self) -> String {
let mut replace = self.string_with_replace_capacity();
for _ in 0..self.trigger {
replace.push_str(self.newline.as_str());
}
replace.push_str(self.text);
replace
}
#[inline]
fn insert_string(&self) -> String {
let mut replace = self.string_with_replace_capacity();
replace.push_str(self.text);
for _ in 0..self.trigger {
replace.push_str(self.newline.as_str());
}
replace
}
#[inline]
fn string_with_replace_capacity(&self) -> String {
let capacity = self.text.len() + self.trigger as usize * self.newline.as_str().len();
String::with_capacity(capacity)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn appender_blank() {
let editor = appender("", 0);
let expected = blank_editor();
assert_eq!(expected, editor);
}
#[test]
fn inserter_blank() {
let editor = inserter("", 0);
let expected = blank_editor();
assert_eq!(expected, editor);
}
#[test]
fn replacer_blank() {
let editor = replacer("", 0);
let expected = blank_editor();
assert_eq!(expected, editor);
}
#[test]
fn appender_crlf_blank() {
let editor = appender_crlf("", 0);
let expected = blank_editor_crlf();
assert_eq!(expected, editor);
}
#[test]
fn inserter_crlf_blank() {
let editor = inserter_crlf("", 0);
let expected = blank_editor_crlf();
assert_eq!(expected, editor);
}
#[test]
fn replacer_crlf_blank() {
let editor = replacer_crlf("", 0);
let expected = blank_editor_crlf();
assert_eq!(expected, editor);
}
#[test]
fn appender_dash_one_line() {
let editor = appender("-", 1);
let expected = Editor::new(String::from("\n-"), 1, NewlineType::Lf);
assert_eq!(expected, editor);
}
#[test]
fn inserter_dash_one_line() {
let editor = inserter("-", 1);
let expected = Editor::new(String::from("-\n"), 1, NewlineType::Lf);
assert_eq!(expected, editor);
}
#[test]
fn replacer_dash_one_line() {
let editor = replacer("-", 1);
let expected = Editor::new(String::from("-"), 1, NewlineType::Lf);
assert_eq!(expected, editor);
}
#[test]
fn appender_crlf_dash_one_line() {
let editor = appender_crlf("-", 1);
let expected = Editor::new(String::from("\r\n-"), 1, NewlineType::Crlf);
assert_eq!(expected, editor);
}
#[test]
fn inserter_crlf_dash_one_line() {
let editor = inserter_crlf("-", 1);
let expected = Editor::new(String::from("-\r\n"), 1, NewlineType::Crlf);
assert_eq!(expected, editor);
}
#[test]
fn replacer_crlf_dash_one_line() {
let editor = replacer_crlf("-", 1);
let expected = Editor::new(String::from("-"), 1, NewlineType::Crlf);
assert_eq!(expected, editor);
}
#[test]
fn appender_dash_two_lines() {
let editor = appender("-", 2);
let expected = Editor::new(String::from("\n\n-"), 2, NewlineType::Lf);
assert_eq!(expected, editor);
}
#[test]
fn inserter_dash_two_lines() {
let editor = inserter("-", 2);
let expected = Editor::new(String::from("-\n\n"), 2, NewlineType::Lf);
assert_eq!(expected, editor);
}
#[test]
fn replacer_dash_two_lines() {
let editor = replacer("-", 2);
let expected = Editor::new(String::from("-"), 2, NewlineType::Lf);
assert_eq!(expected, editor);
}
#[test]
fn appender_crlf_dash_two_lines() {
let editor = appender_crlf("-", 2);
let expected = Editor::new(String::from("\r\n\r\n-"), 2, NewlineType::Crlf);
assert_eq!(expected, editor);
}
#[test]
fn inserter_crlf_dash_two_lines() {
let editor = inserter_crlf("-", 2);
let expected = Editor::new(String::from("-\r\n\r\n"), 2, NewlineType::Crlf);
assert_eq!(expected, editor);
}
#[test]
fn replacer_crlf_dash_two_lines() {
let editor = replacer_crlf("-", 2);
let expected = Editor::new(String::from("-"), 2, NewlineType::Crlf);
assert_eq!(expected, editor);
}
fn blank_editor() -> Editor {
Editor::new(String::from(""), 0, NewlineType::Lf)
}
fn blank_editor_crlf() -> Editor {
Editor::new(String::from(""), 0, NewlineType::Crlf)
}
}