From d57caebe0a823aad7f350eb85f834c787425e5e6 Mon Sep 17 00:00:00 2001
From: Stephen D <webmaster@scd31.com>
Date: Sat, 29 Jun 2024 16:27:31 -0300
Subject: [PATCH] contact deletion

---
 src/controller.rs |  3 +--
 src/storage.rs    | 26 +++++++++++++++++++++-----
 2 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/src/controller.rs b/src/controller.rs
index 1bdc11b..23e9f2e 100644
--- a/src/controller.rs
+++ b/src/controller.rs
@@ -237,8 +237,7 @@ impl Element for Controller {
 
             (View::ContactView(cv, contact_id, _), k) => {
                 if cv.key_push(k) {
-                    // TODO delete contact
-                    // self.storage.contacts((.contacts.remove(*contact_id);
+                    self.storage.delete_contact(*contact_id);
 
                     self.cur_view = View::new_contacts(*contact_id, &self.storage.contacts());
                 }
diff --git a/src/storage.rs b/src/storage.rs
index 131eb47..1215bf8 100644
--- a/src/storage.rs
+++ b/src/storage.rs
@@ -40,12 +40,27 @@ impl Storage {
         if contact.id >= usize::from(len) {
             assert!(usize::from(len) < MAX_CONTACTS);
             self.contact_header.num_contacts += 1;
-            self.contact_header.write(self);
+            let ch = self.contact_header;
+            ch.write(self);
         }
 
         contact.write(self);
     }
 
+    pub fn delete_contact(&mut self, contact_id: usize) {
+        assert!(contact_id < self.contacts_len());
+
+        // Shift every contact down
+        for mut c in self.contacts().skip(contact_id + 1) {
+            c.id -= 1;
+            c.write(self);
+        }
+
+        self.contact_header.num_contacts -= 1;
+        let ch = self.contact_header;
+        ch.write(self);
+    }
+
     pub fn contacts(&self) -> ContactIter {
         ContactIter::new(self.contact_header.num_contacts.into())
     }
@@ -66,7 +81,7 @@ impl Storage {
         }
     }
 
-    fn write_data(&self, start_addr: usize, buf: &[u8]) {
+    fn write_data(&mut self, start_addr: usize, buf: &[u8]) {
         let start_sector = start_addr / SECTOR_SIZE;
         let num_sectors = buf.len() / SECTOR_SIZE + 1;
         let diff = start_addr % SECTOR_SIZE;
@@ -98,7 +113,7 @@ impl Storage {
         buf
     }
 
-    fn write_sector(&self, start_addr: usize, buf: &[u8; 4096]) {
+    fn write_sector(&mut self, start_addr: usize, buf: &[u8; 4096]) {
         let addr: u32 = (start_addr - FLASH_START).try_into().unwrap();
         let sector_size = u32::try_from(SECTOR_SIZE).unwrap();
         assert!(addr % sector_size == 0);
@@ -111,6 +126,7 @@ impl Storage {
 
 // Up to 100 contacts
 // 2 byte CRC checksum
+#[derive(Copy, Clone)]
 struct ContactHeader {
     num_contacts: u8,
 }
@@ -131,7 +147,7 @@ impl ContactHeader {
         }
     }
 
-    fn write(&self, storage: &Storage) {
+    fn write(&self, storage: &mut Storage) {
         let mut buf = [0; CONTACT_HEADER_SIZE];
         buf[0] = self.num_contacts;
         let checksum = X25.checksum(&[self.num_contacts]);
@@ -186,7 +202,7 @@ impl Contact {
         })
     }
 
-    fn write(&self, storage: &Storage) {
+    fn write(&self, storage: &mut Storage) {
         let start_addr = CONTACT_HEADER_START + CONTACT_HEADER_SIZE + self.id * CONTACT_LENGTH;
 
         let mut buf = [0; CONTACT_LENGTH];
-- 
GitLab