Skip to main content

nexus_common/models/user/
view.rs

1use serde::{Deserialize, Serialize};
2use utoipa::ToSchema;
3
4use super::{Relationship, UserCounts, UserDetails};
5use crate::models::tag::traits::TagCollection;
6use crate::models::tag::user::TagUser;
7use crate::models::tag::TagDetails;
8use crate::types::DynError;
9
10/// Represents a Pubky user with relational data including tags, counts, bookmark and relationship with other posts.
11#[derive(Serialize, Deserialize, ToSchema, Default, Debug)]
12pub struct UserView {
13    pub details: UserDetails,
14    pub counts: UserCounts,
15    pub tags: Vec<TagDetails>,
16    pub relationship: Relationship,
17}
18
19impl UserView {
20    /// Retrieves a user by ID, checking the cache first and then the graph database.
21    pub async fn get_by_id(
22        user_id: &str,
23        viewer_id: Option<&str>,
24        depth: Option<u8>,
25    ) -> Result<Option<Self>, DynError> {
26        // Perform all operations concurrently
27        let (details, counts, relationship) = tokio::try_join!(
28            UserDetails::get_by_id(user_id),
29            UserCounts::get_by_id(user_id),
30            Relationship::get_by_id(user_id, viewer_id),
31        )?;
32
33        let details = match details {
34            None => return Ok(None),
35            Some(details) => details,
36        };
37
38        let counts = counts.unwrap_or_default();
39        let relationship = relationship.unwrap_or_default();
40
41        // Before fetching post tags, check if the post has any tags
42        // Without this check, the index search will return a NONE because the tag index
43        // doesn't exist, leading us to query the graph unnecessarily, assuming the data wasn't indexed
44        let tags = match counts.tags {
45            0 => Vec::new(),
46            _ => TagUser::get_by_id(user_id, None, None, None, None, viewer_id, depth)
47                .await?
48                .unwrap_or_default(),
49        };
50
51        Ok(Some(Self {
52            details,
53            counts,
54            relationship,
55            tags,
56        }))
57    }
58}