}
}
-#[derive(Serialize,Deserialize)]
+#[derive(Serialize,Deserialize,Debug)]
pub struct AccountRecord {
pub nick: String,
pub timezone: String,
panic!("xxx")
}
+#[derive(Default,Debug)]
+struct LookupHelper {
+ acctid_r: Option<AccountId>,
+}
+
+impl LookupHelper {
+ #[throws(as Option)]
+ fn get(&mut self, accounts: &Accounts, account: &AccountName) -> AccountId {
+ let acctid = *accounts.names.get(account)?;
+ self.acctid_r = Some(acctid);
+ acctid
+ }
+/*
+ fn finish<T, E>(self) -> impl FnOnce(<T,E>) -> Option<(T, AccountId)>
+ {
+ move |got: Result<T,E>| Some((got.ok()?, self.acctid_r?))
+ }
+*/
+ fn wrap<T, E>(self, got: Result<T,E>) -> Option<(T, AccountId)> {
+ Some((got.ok()?, self.acctid_r?))
+ }
+}
+
impl AccountRecord {
+ pub fn bulk_check(names: &[&AccountName]) -> Vec<Option<AccountId>> {
+ let accounts = ACCOUNTS.read();
+ names.iter().map(|&name|{
+ accounts.as_ref()?.names.get(name).map(|&acctid| acctid)
+ }).collect()
+ }
+
pub fn lookup(account: &AccountName, _: Authorisation<AccountName>)
- -> Option<MappedRwLockReadGuard<'static, AccountRecord>> {
- RwLockReadGuard::try_map(
- ACCOUNTS.read(),
- |accounts| accounts.as_ref()?.get(account)
- ).ok()
+ -> Option<(MappedRwLockReadGuard<'static, AccountRecord>,
+ AccountId)>
+ {
+ let mut helper : LookupHelper = default();
+ helper.wrap(
+ RwLockReadGuard::try_map(ACCOUNTS.read(), |accounts| {
+ let accounts = accounts.as_ref()?;
+ let acctid = helper.get(accounts, account)?;
+ accounts.records.get(acctid)
+ })
+ )
}
- pub fn lookup_mut_caller_must_save(account: &AccountName,
- _auth: Authorisation<AccountName>)
- -> Option<MappedRwLockWriteGuard<'static, AccountRecord>> {
- RwLockWriteGuard::try_map(
- ACCOUNTS.write(),
- |accounts| accounts.as_mut()?.get_mut(account)
- ).ok()
+
+ pub fn lookup_mut_caller_must_save
+ ( account: &AccountName, _auth: Authorisation<AccountName>)
+ -> Option<(MappedRwLockWriteGuard<'static, AccountRecord>,
+ AccountId)>
+ {
+ let mut helper : LookupHelper = default();
+ helper.wrap(
+ RwLockWriteGuard::try_map(ACCOUNTS.write(), |accounts| {
+ let accounts = accounts.as_mut()?;
+ let acctid = helper.get(accounts, account)?;
+ accounts.records.get_mut(acctid)
+ })
+ )
}
#[throws(MgmtError)]
auth: Authorisation<AccountName>,
f: F)
-> Result<T, (InternalError, T)>
- where F: FnOnce(&mut AccountRecord) -> T
+ where F: FnOnce(&mut AccountRecord, AccountId) -> T
{
let entry = AccountRecord::lookup_mut_caller_must_save(account, auth)
.ok_or(MgmtError::AccountNotFound)?;
let old_access = entry.access.clone();
let output = f(entry);
let mut ok = true;
- if ! Arc::ptr_eq(old_access, entry.access) {
-// xxx actually do this
+ if_chain!{
+ if let Some(entry) = entry;
+ if Arc::ptr_eq(old_access, entry.access);
+ then {
+ // xxx actually do this
// invalidate_all_tokens_for_account(accid)
// .dont_just_questionmark
- }
+ }
+ };
let ok = if entry.is_some() { save_accounts_now() } else { Ok(()) };
match ok {
Ok(()) => Ok(output),
pub struct InstanceAccessDetails<Id> {
pub gref : InstanceRef,
pub ident : Id,
- pub accid : AccountId,
+ pub acctid : AccountId,
}
#[derive(Clone,Debug)]
.ok_or(MgmtError::PlayerNotFound)?
.pst;
- let access = AccountRecord::with_entry_mut(
+ let (access, acctid) = AccountRecord::with_entry_mut(
&pst.account, authorised,
|acct, acctid|
{
})
.latest = now;
acct.expire_tokens_revealed();
- Ok::<_,MgmtError>(access.clone())
+ Ok::<_,MgmtError>((access.clone(), acctid))
})?.map_err(|(e,_)|e)??;
if reset {
let iad = InstanceAccessDetails {
gref : self.gref.clone(),
- ident : player
+ ident : player,
+ acctid
};
self.token_register(token.clone(), iad);
}
let name = Arc::new(name);
- tokens_players.retain(
- |&(_,player)| gs.players.contains_key(player)
- );
+ let (tokens_players, acctids_players) = {
+ let mut tokens = Vec::with_capacity(tokens_players.len());
+ let mut acctnames = Vec::with_capacity(tokens_players.len());
+ for (token, player) in tokens_players { if_chain! {
+ if let Some(name) = gs.players.get(player);
+ then {
+ tokens.push((token, player));
+ acctnames.push(name);
+ }
+ }}
+ (tokens, AccountRecord::bulk_check(&acctnames))
+ };
let g = Instance {
gs, iplayers,
g.tokens_players.tr.insert(RawToken(token.clone()));
}
let mut global = GLOBAL.players.write().unwrap();
- for (token, player) in tokens_players.drain(0..) {
+ for ((token, player), acctid) in
+ tokens_players.drain(0..)
+ .zip(acctids_players)
+ { if_chain!{
+ if let Some(acctid) = acctid;
let iad = InstanceAccessDetails {
+ acctid,
gref : gref.clone(),
ident : player,
};
- global.insert(RawToken(token), iad);
- }
+ then { global.insert(RawToken(token), iad); }
+ } }
drop(global);
drop(g);
GLOBAL.games.write().unwrap().insert(name.clone(), gref.clone());