mostro_core/
rating.rs

1use nostr_sdk::prelude::*;
2use serde::{Deserialize, Serialize};
3
4use crate::error::ServiceError;
5
6/// We use this struct to create a user reputation
7#[derive(Debug, Deserialize, Serialize, Clone)]
8pub struct Rating {
9    pub total_reviews: u64,
10    pub total_rating: f64,
11    pub last_rating: u8,
12    pub max_rate: u8,
13    pub min_rate: u8,
14}
15
16impl Rating {
17    pub fn new(
18        total_reviews: u64,
19        total_rating: f64,
20        last_rating: u8,
21        min_rate: u8,
22        max_rate: u8,
23    ) -> Self {
24        Self {
25            total_reviews,
26            total_rating,
27            last_rating,
28            min_rate,
29            max_rate,
30        }
31    }
32
33    /// New order from json string
34    pub fn from_json(json: &str) -> Result<Self, ServiceError> {
35        serde_json::from_str(json).map_err(|_| ServiceError::MessageSerializationError)
36    }
37
38    /// Get order as json string
39    pub fn as_json(&self) -> Result<String, ServiceError> {
40        serde_json::to_string(&self).map_err(|_| ServiceError::MessageSerializationError)
41    }
42
43    /// Transform Rating struct to tuple vector to easily interact with Nostr
44    pub fn to_tags(&self) -> Result<Tags> {
45        let tags = vec![
46            Tag::custom(
47                TagKind::Custom(std::borrow::Cow::Borrowed("total_reviews")),
48                vec![self.total_reviews.to_string()],
49            ),
50            Tag::custom(
51                TagKind::Custom(std::borrow::Cow::Borrowed("total_rating")),
52                vec![self.total_rating.to_string()],
53            ),
54            Tag::custom(
55                TagKind::Custom(std::borrow::Cow::Borrowed("last_rating")),
56                vec![self.last_rating.to_string()],
57            ),
58            Tag::custom(
59                TagKind::Custom(std::borrow::Cow::Borrowed("max_rate")),
60                vec![self.max_rate.to_string()],
61            ),
62            Tag::custom(
63                TagKind::Custom(std::borrow::Cow::Borrowed("min_rate")),
64                vec![self.min_rate.to_string()],
65            ),
66            Tag::custom(
67                TagKind::Custom(std::borrow::Cow::Borrowed("z")),
68                vec!["rating".to_string()],
69            ),
70        ];
71
72        let tags = Tags::from_list(tags);
73
74        Ok(tags)
75    }
76
77    /// Transform tuple vector to Rating struct
78    pub fn from_tags(tags: Tags) -> Result<Self, ServiceError> {
79        let mut total_reviews = 0;
80        let mut total_rating = 0.0;
81        let mut last_rating = 0;
82        let mut max_rate = 0;
83        let mut min_rate = 0;
84
85        for tag in tags.into_iter() {
86            let t = tag.to_vec();
87            let key = t
88                .first()
89                .ok_or_else(|| ServiceError::NostrError("Missing tag key".to_string()))?;
90            let value = t
91                .get(1)
92                .ok_or_else(|| ServiceError::NostrError("Missing tag value".to_string()))?;
93            match key.as_str() {
94                "total_reviews" => {
95                    total_reviews = value
96                        .parse::<u64>()
97                        .map_err(|_| ServiceError::ParsingNumberError)?
98                }
99                "total_rating" => {
100                    total_rating = value
101                        .parse::<f64>()
102                        .map_err(|_| ServiceError::ParsingNumberError)?
103                }
104                "last_rating" => {
105                    last_rating = value
106                        .parse::<u8>()
107                        .map_err(|_| ServiceError::ParsingNumberError)?
108                }
109                "max_rate" => {
110                    max_rate = value
111                        .parse::<u8>()
112                        .map_err(|_| ServiceError::ParsingNumberError)?
113                }
114                "min_rate" => {
115                    min_rate = value
116                        .parse::<u8>()
117                        .map_err(|_| ServiceError::ParsingNumberError)?
118                }
119                _ => {}
120            }
121        }
122
123        Ok(Self {
124            total_reviews,
125            total_rating,
126            last_rating,
127            max_rate,
128            min_rate,
129        })
130    }
131}