nexus_common/models/post/
view.rs1use serde::{Deserialize, Serialize};
2use utoipa::ToSchema;
3
4use super::{Bookmark, PostCounts, PostDetails, PostRelationships};
5use crate::models::tag::post::TagPost;
6use crate::models::tag::traits::TagCollection;
7use crate::models::tag::TagDetails;
8use crate::types::DynError;
9
10#[derive(Serialize, Deserialize, ToSchema, Default, Debug)]
12pub struct PostView {
13 pub details: PostDetails,
14 pub counts: PostCounts,
15 pub tags: Vec<TagDetails>,
16 pub relationships: PostRelationships,
17 pub bookmark: Option<Bookmark>,
18}
19
20impl PostView {
21 pub async fn get_by_id(
23 author_id: &str,
24 post_id: &str,
25 viewer_id: Option<&str>,
26 limit_tags: Option<usize>,
27 limit_taggers: Option<usize>,
28 ) -> Result<Option<Self>, DynError> {
29 let (details, counts, bookmark, relationships) = tokio::try_join!(
31 PostDetails::get_by_id(author_id, post_id),
32 PostCounts::get_by_id(author_id, post_id),
33 Bookmark::get_by_id(author_id, post_id, viewer_id),
34 PostRelationships::get_by_id(author_id, post_id),
35 )?;
36
37 let details = match details {
38 None => return Ok(None),
39 Some(details) => details,
40 };
41
42 let counts = counts.unwrap_or_default();
43 let relationships = relationships.unwrap_or_default();
44
45 let tags = match counts.tags {
49 0 => Vec::new(),
50 _ => {
51 TagPost::get_by_id(
52 author_id,
53 Some(post_id),
54 None,
55 limit_tags,
56 limit_taggers,
57 viewer_id,
58 None, )
60 .await?
61 .unwrap_or_default()
62 }
63 };
64
65 Ok(Some(Self {
66 details,
67 counts,
68 bookmark,
69 relationships,
70 tags,
71 }))
72 }
73}