use crate::{aĆ­tentigo::UzantIdentigilo, datumbazo::Datumbazo}; use rusqlite::{params, OptionalExtension}; use std::collections::{HashMap, HashSet}; #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct Rajto(String); impl From<&str> for Rajto { fn from(s: &str) -> Self { Rajto(s.to_owned()) } } impl From for String { fn from(s: Rajto) -> Self { s.0.clone() } } pub trait Rajtigo { fn havas_rajton<'a, F>(&'a self, identigilo: UzantIdentigilo, provo: F) -> bool where F: FnOnce(&mut (dyn Iterator)) -> bool; fn rajtoj(&self, identigilo: &UzantIdentigilo) -> Vec; fn aldonu_rajtojn( &mut self, identigilo: UzantIdentigilo, rajtoj: &mut (dyn Iterator), ); fn foriru_rajtoj( &mut self, identigilo: UzantIdentigilo, rajtoj: &mut (dyn Iterator), ); fn foriru_uzanto(&mut self, identigilo: UzantIdentigilo); } /* pub struct MemRajtigo { rajtoj: HashMap>, } impl MemRajtigo { pub fn new() -> Self { MemRajtigo { rajtoj: HashMap::new(), } } } impl Rajtigo for MemRajtigo { fn havas_rajton<'a, F>(&'a self, identigilo: UzantIdentigilo, provo: F) -> bool where F: FnOnce(&mut (dyn Iterator + 'a)) -> bool, { match self.rajtoj.get(&identigilo) { Some(rajtoj) => provo(&mut rajtoj.clone().into_iter()), None => false, } } fn rajtoj(&self, identigilo: &UzantIdentigilo) -> Vec { self.rajtoj .get(&identigilo) .map(|r| r.into_iter().cloned().collect::>()) .unwrap_or(vec![]) } fn aldonu_rajtoj( &mut self, identigilo: UzantIdentigilo, rajtoj: &mut (dyn Iterator), ) { let valoro = self.rajtoj.entry(identigilo).or_insert(HashSet::new()); while let Some(r) = rajtoj.next() { valoro.insert(r); } } fn foriru_rajtoj( &mut self, identigilo: UzantIdentigilo, rajtoj: &mut (dyn Iterator), ) { let valoro = self.rajtoj.entry(identigilo).or_insert(HashSet::new()); while let Some(r) = rajtoj.next() { valoro.remove(&r); } } fn foriru_uzanto(&mut self, identigilo: UzantIdentigilo) { let _ = self.rajtoj.remove(&identigilo); } } */ pub struct DBRajtigo { pool: Datumbazo, } impl DBRajtigo { pub fn kreu(pool: Datumbazo) -> Self { DBRajtigo { pool } } } impl Rajtigo for DBRajtigo { fn havas_rajton<'a, F>(&'a self, identigilo: UzantIdentigilo, provo: F) -> bool where F: FnOnce(&mut (dyn Iterator)) -> bool, { let konekto = self.pool.konektu().unwrap(); let mut stmt = konekto .prepare("SELECT rajto FROM rajtoj WHERE uzanto = ?") .unwrap(); let mut rajtoj = stmt .query_map([String::from(identigilo)], |row| { row.get("rajto").map(|s: String| Rajto::from(s.as_ref())) }) .unwrap() .map(|r| r.unwrap()); provo(&mut rajtoj) } fn rajtoj(&self, identigilo: &UzantIdentigilo) -> Vec { vec![] } fn aldonu_rajtojn( &mut self, identigilo: UzantIdentigilo, rajtoj: &mut (dyn Iterator), ) { let konekto = self.pool.konektu().unwrap(); let mut stmt = konekto.prepare("INSERT INTO rajtoj VALUES(?, ?)").unwrap(); rajtoj.for_each(|r| { stmt.execute(params![String::from(identigilo.clone()), String::from(r)]) .unwrap(); }); } fn foriru_rajtoj( &mut self, identigilo: UzantIdentigilo, rajtoj: &mut (dyn Iterator), ) { } fn foriru_uzanto(&mut self, identigilo: UzantIdentigilo) {} }