use std::collections::HashSet;
use tokio::io::{AsyncRead, AsyncWrite};
use tokio_util::codec::Framed;
use crate::conn::sendrecv;
use crate::types::ObjRef;
use crate::err::Error;
#[derive(Debug)]
pub struct Account {
pub id: i64,
pub name: String,
pub lock: bool,
pub perms: HashSet<String>
}
pub async fn rd<T>(
conn: &mut Framed<T, blather::Codec>,
acc: Option<ObjRef>
) -> Result<Account, Error>
where
T: AsyncRead + AsyncWrite + Unpin
{
let mut tg = blather::Telegram::new_topic("RdAcc")?;
if let Some(acc) = acc {
match acc {
ObjRef::Id(id) => {
tg.add_param("Id", id)?;
}
ObjRef::Name(nm) => {
tg.add_str("Name", &nm)?;
}
}
}
let params = sendrecv(conn, &tg).await?;
let id = params.get_int::<i64>("Id")?;
let name = params.get_param::<String>("Name")?;
let lock = params.get_bool("Lock")?;
let perms = params.get_hashset("Perms")?;
let acc = Account {
id,
name,
lock,
perms
};
Ok(acc)
}
#[derive(Debug)]
pub struct LsEntry {
pub id: i64,
pub name: String
}
pub async fn ls<T>(
conn: &mut Framed<T, blather::Codec>,
inclock: bool
) -> Result<Vec<LsEntry>, Error>
where
T: AsyncRead + AsyncWrite + Unpin
{
let mut tg = blather::Telegram::new_topic("LsAcc")?;
if inclock {
tg.add_bool("All", true)?;
}
let params = sendrecv(conn, &tg).await?;
let num_entries = params.get_int::<usize>("#")?;
let mut acclist = Vec::with_capacity(num_entries);
for i in 0..num_entries {
let id = format!("{}.Id", i);
let name = format!("{}.Name", i);
acclist.push(LsEntry {
id: params.get_int::<i64>(&id).unwrap(),
name: params.get_str(&name).unwrap().to_string()
});
}
Ok(acclist)
}
pub enum ModPerms {
Set(HashSet<String>),
Grant(HashSet<String>),
Revoke(HashSet<String>),
GrantRevoke(HashSet<String>, HashSet<String>)
}
pub struct WrAccount {
pub name: Option<String>,
pub username: Option<String>,
pub lock: Option<bool>,
pub perms: Option<ModPerms>
}
pub async fn wr<T>(
conn: &mut Framed<T, blather::Codec>,
acc: ObjRef,
ai: WrAccount
) -> Result<(), Error>
where
T: AsyncRead + AsyncWrite + Unpin
{
let mut tg = blather::Telegram::new_topic("WrAcc")?;
match acc {
ObjRef::Id(id) => {
tg.add_param("Id", id)?;
}
ObjRef::Name(nm) => {
tg.add_str("Name", &nm)?;
}
}
if let Some(name) = ai.name {
tg.add_str("NewName", &name)?;
}
if let Some(username) = ai.username {
tg.add_str("UserName", &username)?;
}
if let Some(lck) = ai.lock {
tg.add_bool("Lock", lck)?;
}
if let Some(perms) = ai.perms {
match perms {
ModPerms::Set(set) => {
tg.add_strit("Perms", set.iter())?;
}
ModPerms::Grant(set) => {
tg.add_strit("Grant", set.iter())?;
}
ModPerms::Revoke(set) => {
tg.add_strit("Revoke", set.iter())?;
}
ModPerms::GrantRevoke(grant, revoke) => {
tg.add_strit("Grant", grant.iter())?;
tg.add_strit("Revoke", revoke.iter())?;
}
}
}
sendrecv(conn, &tg).await?;
Ok(())
}
pub async fn rm<T>(
conn: &mut Framed<T, blather::Codec>,
acc: ObjRef
) -> Result<(), Error>
where
T: AsyncRead + AsyncWrite + Unpin
{
let mut tg = blather::Telegram::new_topic("RmAcc")?;
match acc {
ObjRef::Id(id) => {
tg.add_param("Id", id)?;
}
ObjRef::Name(nm) => {
tg.add_str("Name", &nm)?;
}
}
sendrecv(conn, &tg).await?;
Ok(())
}