mirror of https://github.com/CympleTech/ESSE.git
5 changed files with 175 additions and 189 deletions
@ -1,182 +0,0 @@
@@ -1,182 +0,0 @@
|
||||
use std::collections::HashMap; |
||||
use std::path::PathBuf; |
||||
use tdn::types::{ |
||||
group::GroupId, |
||||
primitive::{new_io_error, PeerAddr, Result}, |
||||
}; |
||||
|
||||
use crate::apps::chat::Friend; |
||||
use crate::storage::session_db; |
||||
|
||||
/// online info.
|
||||
pub enum Online { |
||||
/// connected to this device.
|
||||
Direct(PeerAddr), |
||||
/// connected to other device.
|
||||
Relay(PeerAddr), |
||||
} |
||||
|
||||
impl Online { |
||||
fn addr(&self) -> &PeerAddr { |
||||
match self { |
||||
Online::Direct(ref addr) | Online::Relay(ref addr) => addr, |
||||
} |
||||
} |
||||
} |
||||
|
||||
pub(crate) struct RunningAccount { |
||||
permissioned: HashMap<GroupId, i64>, |
||||
/// online group (friends/services) => group's address.
|
||||
onlines: HashMap<GroupId, Online>, |
||||
} |
||||
|
||||
impl RunningAccount { |
||||
pub fn init(base: &PathBuf, gid: &GroupId) -> Result<Self> { |
||||
let mut permissioned = HashMap::new(); |
||||
|
||||
// load friends to cache.
|
||||
let db = session_db(base, gid)?; |
||||
let friends = Friend::all_id(&db)?; |
||||
for (fgid, db_id) in friends { |
||||
permissioned.insert(fgid, db_id); |
||||
} |
||||
|
||||
// TODO load services to cache.
|
||||
|
||||
// TODO load permissioned
|
||||
Ok(RunningAccount { |
||||
permissioned, |
||||
onlines: HashMap::new(), |
||||
}) |
||||
} |
||||
|
||||
/// get all onlines's groupid
|
||||
pub fn online_groups(&self) -> Vec<&GroupId> { |
||||
self.onlines.keys().map(|k| k).collect() |
||||
} |
||||
|
||||
/// get online peer's addr.
|
||||
pub fn online(&self, gid: &GroupId) -> Result<PeerAddr> { |
||||
self.onlines |
||||
.get(gid) |
||||
.map(|online| *online.addr()) |
||||
.ok_or(new_io_error("remote not online")) |
||||
} |
||||
|
||||
pub fn online_direct(&self, gid: &GroupId) -> Result<PeerAddr> { |
||||
if let Some(online) = self.onlines.get(gid) { |
||||
match online { |
||||
Online::Direct(addr) => return Ok(*addr), |
||||
_ => {} |
||||
} |
||||
} |
||||
Err(new_io_error("no direct online")) |
||||
} |
||||
|
||||
/// get all online peer.
|
||||
pub fn onlines(&self) -> Vec<(&GroupId, &PeerAddr)> { |
||||
self.onlines |
||||
.iter() |
||||
.map(|(fgid, online)| (fgid, online.addr())) |
||||
.collect() |
||||
} |
||||
|
||||
/// check add online.
|
||||
pub fn check_add_online(&mut self, gid: GroupId, online: Online) -> Result<()> { |
||||
if let Some(o) = self.onlines.get(&gid) { |
||||
match (o, &online) { |
||||
(Online::Relay(..), Online::Direct(..)) => { |
||||
self.onlines.insert(gid, online); |
||||
Ok(()) |
||||
} |
||||
_ => Err(new_io_error("remote had online")), |
||||
} |
||||
} else { |
||||
self.onlines.insert(gid, online); |
||||
Ok(()) |
||||
} |
||||
} |
||||
|
||||
/// check offline, and return is direct.
|
||||
pub fn check_offline(&mut self, gid: &GroupId, addr: &PeerAddr) -> bool { |
||||
if let Some(online) = self.onlines.remove(gid) { |
||||
if online.addr() != addr { |
||||
return false; |
||||
} |
||||
|
||||
match online { |
||||
Online::Direct(..) => { |
||||
return true; |
||||
} |
||||
_ => {} |
||||
} |
||||
} |
||||
false |
||||
} |
||||
|
||||
/// remove all onlines peer.
|
||||
pub fn remove_onlines(self) -> Vec<(PeerAddr, GroupId)> { |
||||
let mut peers = vec![]; |
||||
for (fgid, online) in self.onlines { |
||||
match online { |
||||
Online::Direct(addr) => peers.push((addr, fgid)), |
||||
_ => {} |
||||
} |
||||
} |
||||
peers |
||||
} |
||||
|
||||
/// check if addr is online.
|
||||
pub fn check_addr_online(&self, addr: &PeerAddr) -> bool { |
||||
for (_, online) in &self.onlines { |
||||
if online.addr() == addr { |
||||
return true; |
||||
} |
||||
} |
||||
false |
||||
} |
||||
|
||||
/// peer leave, remove online peer.
|
||||
pub fn peer_leave(&mut self, addr: &PeerAddr) -> Vec<(GroupId, i64)> { |
||||
let mut peers = vec![]; |
||||
for (fgid, online) in &self.onlines { |
||||
if online.addr() == addr { |
||||
if let Some(i) = self.permissioned.get(fgid) { |
||||
peers.push((*fgid, *i)) |
||||
} |
||||
} |
||||
} |
||||
|
||||
for i in &peers { |
||||
self.onlines.remove(&i.0); |
||||
} |
||||
peers |
||||
} |
||||
|
||||
/// add the permissioned group.
|
||||
pub fn add_permissioned(&mut self, gid: GroupId, id: i64) { |
||||
self.permissioned.insert(gid, id); |
||||
} |
||||
|
||||
/// remove the permissioned group.
|
||||
pub fn remove_permissioned(&mut self, gid: &GroupId) -> Option<PeerAddr> { |
||||
self.permissioned.remove(gid); |
||||
self.onlines.remove(gid).and_then(|o| match o { |
||||
Online::Direct(addr) => Some(addr), |
||||
_ => None, |
||||
}) |
||||
} |
||||
|
||||
/// check the group is permissioned.
|
||||
pub fn get_permissioned(&self, gid: &GroupId) -> Result<i64> { |
||||
self.permissioned |
||||
.get(gid) |
||||
.cloned() |
||||
.ok_or(new_io_error("remote missing")) |
||||
} |
||||
|
||||
/// list all onlines groups.
|
||||
pub fn _list_onlines(&self) -> Vec<(&GroupId, &PeerAddr)> { |
||||
self.onlines.iter().map(|(k, v)| (k, v.addr())).collect() |
||||
} |
||||
} |
Loading…
Reference in new issue