user.rs

 1use crate::rpc::Client;
 2use anyhow::{anyhow, Result};
 3use parking_lot::Mutex;
 4use std::{collections::HashMap, sync::Arc};
 5use zrpc::proto;
 6
 7pub use proto::User;
 8
 9pub struct UserStore {
10    users: Mutex<HashMap<u64, Arc<User>>>,
11    rpc: Arc<Client>,
12}
13
14impl UserStore {
15    pub fn new(rpc: Arc<Client>) -> Self {
16        Self {
17            users: Default::default(),
18            rpc,
19        }
20    }
21
22    pub async fn load_users(&self, mut user_ids: Vec<u64>) -> Result<()> {
23        {
24            let users = self.users.lock();
25            user_ids.retain(|id| !users.contains_key(id));
26        }
27
28        if !user_ids.is_empty() {
29            let response = self.rpc.request(proto::GetUsers { user_ids }).await?;
30            let mut users = self.users.lock();
31            for user in response.users {
32                users.insert(user.id, Arc::new(user));
33            }
34        }
35
36        Ok(())
37    }
38
39    pub async fn get_user(&self, user_id: u64) -> Result<Arc<User>> {
40        if let Some(user) = self.users.lock().get(&user_id).cloned() {
41            return Ok(user);
42        }
43
44        let response = self
45            .rpc
46            .request(proto::GetUsers {
47                user_ids: vec![user_id],
48            })
49            .await?;
50
51        if let Some(user) = response.users.into_iter().next() {
52            let user = Arc::new(user);
53            self.users.lock().insert(user_id, user.clone());
54            Ok(user)
55        } else {
56            Err(anyhow!("server responded with no users"))
57        }
58    }
59}