1use std::collections::HashSet;
2
3use tokio::io::{AsyncRead, AsyncWrite};
4
5use tokio_util::codec::Framed;
6
7use crate::conn::sendrecv;
8use crate::types::ObjRef;
9
10use crate::err::Error;
11
12
13#[derive(Debug)]
14pub struct Account {
15 pub id: i64,
16 pub name: String,
17 pub lock: bool,
18 pub perms: HashSet<String>
19}
20
21
22pub async fn rd<T>(
26 conn: &mut Framed<T, blather::Codec>,
27 acc: Option<ObjRef>
28) -> Result<Account, Error>
29where
30 T: AsyncRead + AsyncWrite + Unpin
31{
32 let mut tg = blather::Telegram::new_topic("RdAcc")?;
33
34 if let Some(acc) = acc {
35 match acc {
36 ObjRef::Id(id) => {
37 tg.add_param("Id", id)?;
38 }
39 ObjRef::Name(nm) => {
40 tg.add_str("Name", &nm)?;
41 }
42 }
43 }
44
45 let params = sendrecv(conn, &tg).await?;
46
47 let id = params.get_int::<i64>("Id")?;
48 let name = params.get_param::<String>("Name")?;
49 let lock = params.get_bool("Lock")?;
50 let perms = params.get_hashset("Perms")?;
51
52 let acc = Account {
53 id,
54 name,
55 lock,
56 perms
57 };
58
59 Ok(acc)
60}
61
62
63#[derive(Debug)]
64pub struct LsEntry {
65 pub id: i64,
66 pub name: String
67}
68
69
70pub async fn ls<T>(
77 conn: &mut Framed<T, blather::Codec>,
78 inclock: bool
79) -> Result<Vec<LsEntry>, Error>
80where
81 T: AsyncRead + AsyncWrite + Unpin
82{
83 let mut tg = blather::Telegram::new_topic("LsAcc")?;
84
85 if inclock {
86 tg.add_bool("All", true)?;
87 }
88
89 let params = sendrecv(conn, &tg).await?;
90
91 let num_entries = params.get_int::<usize>("#")?;
92
93 let mut acclist = Vec::with_capacity(num_entries);
94 for i in 0..num_entries {
95 let id = format!("{}.Id", i);
96 let name = format!("{}.Name", i);
97
98 acclist.push(LsEntry {
99 id: params.get_int::<i64>(&id).unwrap(),
100 name: params.get_str(&name).unwrap().to_string()
101 });
102 }
103
104 Ok(acclist)
105}
106
107
108pub enum ModPerms {
110 Set(HashSet<String>),
113
114 Grant(HashSet<String>),
117
118 Revoke(HashSet<String>),
121
122 GrantRevoke(HashSet<String>, HashSet<String>)
124}
125
126
127pub struct WrAccount {
129 pub name: Option<String>,
132
133 pub username: Option<String>,
135
136 pub lock: Option<bool>,
138
139 pub perms: Option<ModPerms>
142}
143
144
145pub async fn wr<T>(
147 conn: &mut Framed<T, blather::Codec>,
148 acc: ObjRef,
149 ai: WrAccount
150) -> Result<(), Error>
151where
152 T: AsyncRead + AsyncWrite + Unpin
153{
154 let mut tg = blather::Telegram::new_topic("WrAcc")?;
155
156 match acc {
157 ObjRef::Id(id) => {
158 tg.add_param("Id", id)?;
159 }
160 ObjRef::Name(nm) => {
161 tg.add_str("Name", &nm)?;
162 }
163 }
164
165 if let Some(name) = ai.name {
166 tg.add_str("NewName", &name)?;
167 }
168 if let Some(username) = ai.username {
169 tg.add_str("UserName", &username)?;
170 }
171 if let Some(lck) = ai.lock {
172 tg.add_bool("Lock", lck)?;
173 }
174
175 if let Some(perms) = ai.perms {
176 match perms {
177 ModPerms::Set(set) => {
178 tg.add_strit("Perms", set.iter())?;
179 }
180 ModPerms::Grant(set) => {
181 tg.add_strit("Grant", set.iter())?;
182 }
183 ModPerms::Revoke(set) => {
184 tg.add_strit("Revoke", set.iter())?;
185 }
186 ModPerms::GrantRevoke(grant, revoke) => {
187 tg.add_strit("Grant", grant.iter())?;
188 tg.add_strit("Revoke", revoke.iter())?;
189 }
190 }
191 }
192
193 sendrecv(conn, &tg).await?;
194
195 Ok(())
196}
197
198
199pub async fn rm<T>(
201 conn: &mut Framed<T, blather::Codec>,
202 acc: ObjRef
203) -> Result<(), Error>
204where
205 T: AsyncRead + AsyncWrite + Unpin
206{
207 let mut tg = blather::Telegram::new_topic("RmAcc")?;
208
209 match acc {
210 ObjRef::Id(id) => {
211 tg.add_param("Id", id)?;
212 }
213 ObjRef::Name(nm) => {
214 tg.add_str("Name", &nm)?;
215 }
216 }
217
218 sendrecv(conn, &tg).await?;
219
220 Ok(())
221}
222
223