From 394232a49789c05e85057a22c19cd79d48f0f548 Mon Sep 17 00:00:00 2001
From: rick <rick@gnous.eu>
Date: Sun, 23 Apr 2023 01:11:46 +0200
Subject: [PATCH] add append command

---
 src/buffer.rs | 17 +++++++++++++++++
 src/enums.rs  | 16 ++++++++++++++++
 src/main.rs   | 20 +++++++++++++++++++-
 3 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/src/buffer.rs b/src/buffer.rs
index b6e2d07..3a552db 100644
--- a/src/buffer.rs
+++ b/src/buffer.rs
@@ -28,6 +28,23 @@ impl Buffer {
         self.current_line = new;
     }
 
+    pub fn append(&mut self, addr: Address, lines: Vec<String>) {
+        self.has_changed = true;
+        match addr {
+            Address::Actual => self.append_buffer(self.current_line, lines),
+            Address::Line(l) => self.append_buffer(l, lines),
+            Address::Last => self.append_buffer(self.buffer.len(), lines),
+            _ => (),
+        }
+    }
+
+    fn append_buffer(&mut self, line: usize, lines: Vec<String>) {
+        for (i, l) in lines.iter().enumerate() {
+            self.buffer.insert(i + line, Ok(l.to_string()));
+            self.current_line = i + line;
+        }
+    }
+
     pub fn print(&mut self, addr: Address, print_numbers: bool) {
         let last_line = self.buffer.len();
         match addr {
diff --git a/src/enums.rs b/src/enums.rs
index 14e16da..0238e89 100644
--- a/src/enums.rs
+++ b/src/enums.rs
@@ -15,6 +15,15 @@ pub enum Address {
     Null,
 }
 
+impl Address {
+    pub fn is_multi_line(&self) -> bool {
+        match self {
+            Address::Null | Address::Actual | Address::Last | Address::Line(_) => false,
+            _ => true,
+        }
+    }
+}
+
 pub fn parse_address(addr: &str) -> Address {
     let mut tmp = String::from(addr);
     tmp.retain(|c| c != ' ');
@@ -138,6 +147,13 @@ fn parse_without_addr(c: char) -> Command {
 
 fn parse(c: char, addr: Address) -> Result<Command, String> {
     match c {
+        'a' => {
+            if addr.is_multi_line() {
+                Err(String::from("Erreur d'adresse"))
+            }  else {
+                Ok(Command::Append(addr))
+            }
+        },
         'p' => Ok(Command::Print(addr)),
         'n' => Ok(Command::Number(addr)),
         'q' => Ok(Command::Quit(false)),
diff --git a/src/main.rs b/src/main.rs
index fb8953a..abacf81 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -45,6 +45,24 @@ fn execute_command(buffer: &mut Buffer, c: Command) -> bool {
     let mut ret = false;
 
     match c {
+        Command::Append(a) => {
+            let mut new_lines: Vec<String> = Vec::new();
+            let mut buffer_input = String::new();
+            while buffer_input != "." {
+                buffer_input.clear();
+                match io::stdin().read_line(&mut buffer_input) {
+                    Ok(_) => {
+                        buffer_input.pop();
+                        if buffer_input != "." {
+                            new_lines.push(buffer_input.clone());
+                        }
+                    },
+                    Err(e) => panic!("{}", e),
+                }
+            }
+
+            buffer.append(a, new_lines);
+        },
         Command::Print(a) => buffer.print(a, false),
         Command::Number(a) => buffer.print(a, true),
         Command::Quit(_) => ret = true,
@@ -56,7 +74,7 @@ fn execute_command(buffer: &mut Buffer, c: Command) -> bool {
 
 fn parse_line(input: &str) -> Result<Command, String> {
     let address = take_while(check_address_complete);
-    let command = one_of::<_, _, (&str, ErrorKind)>("pnqQ");
+    let command = one_of::<_, _, (&str, ErrorKind)>("apnqQ");
 
     //if let Ok((input, (a, c))) = alt(address, command).parse(input) {
     let tmp = (address, command).parse(input);