/ src / profile / proxy / rule.rs
rule.rs
  1  mod database;
  2  mod memory;
  3  
  4  use anyhow::Result;
  5  use database::Database;
  6  use gtk::glib::DateTime;
  7  use memory::Memory;
  8  use r2d2::Pool;
  9  use r2d2_sqlite::SqliteConnectionManager;
 10  use std::cell::RefCell;
 11  
 12  pub struct Rule {
 13      database: Database,
 14      memory: RefCell<Vec<Memory>>,
 15  }
 16  
 17  impl Rule {
 18      // Constructors
 19  
 20      pub fn init(database_pool: &Pool<SqliteConnectionManager>, profile_id: i64) -> Result<Self> {
 21          let database = Database::init(database_pool, profile_id);
 22  
 23          let rows = database.rows()?;
 24          let memory = RefCell::new(Vec::with_capacity(rows.len()));
 25  
 26          {
 27              // build in-memory index...
 28              let mut m = memory.borrow_mut();
 29              for row in rows {
 30                  m.push(Memory {
 31                      id: Some(row.id),
 32                      is_enabled: row.is_enabled,
 33                      priority: row.priority,
 34                      request: row.request,
 35                      time: DateTime::from_unix_local(row.time)?,
 36                      url: row.url,
 37                  });
 38              }
 39          }
 40  
 41          Ok(Self { database, memory })
 42      }
 43  
 44      // Setters
 45  
 46      pub fn add(
 47          &self,
 48          id: Option<i64>,
 49          is_enabled: bool,
 50          priority: i32,
 51          request: String,
 52          url: String,
 53          time: DateTime,
 54      ) {
 55          self.memory.borrow_mut().push(Memory {
 56              id,
 57              time,
 58              is_enabled,
 59              priority,
 60              request,
 61              url,
 62          }) // @TODO validate?
 63      }
 64  
 65      pub fn clear(&self) {
 66          self.memory.borrow_mut().clear();
 67      }
 68  
 69      pub fn save(&self) -> Result<()> {
 70          let rules = self.memory.take();
 71          let mut keep_id = Vec::with_capacity(rules.len());
 72          for rule in rules {
 73              keep_id.push(self.database.persist(
 74                  rule.id,
 75                  rule.time.to_unix(),
 76                  rule.is_enabled,
 77                  rule.priority,
 78                  rule.request,
 79                  rule.url,
 80              )?);
 81          }
 82          self.database.clean(keep_id)?;
 83          Ok(())
 84      }
 85  
 86      // Getters
 87  
 88      pub fn all(&self) -> Vec<Memory> {
 89          self.memory.borrow().iter().cloned().collect()
 90      }
 91  
 92      pub fn enabled(&self) -> Vec<Memory> {
 93          self.memory
 94              .borrow()
 95              .iter()
 96              .filter(|r| r.is_enabled)
 97              .cloned()
 98              .collect()
 99      }
100  }
101  
102  // Tools
103  
104  pub fn migrate(tx: &sqlite::Transaction) -> Result<()> {
105      // Migrate self components
106      database::init(tx)?;
107  
108      // Delegate migration to childs
109      // nothing yet...
110  
111      // Success
112      Ok(())
113  }