Skip to main content

stateset_embedded/
reviews.rs

1//! Product review operations for managing customer reviews and ratings
2//!
3//! # Example
4//!
5//! ```rust,ignore
6//! use stateset_embedded::{Commerce, CreateReview, ProductId, CustomerId};
7//!
8//! let commerce = Commerce::new("./store.db")?;
9//!
10//! let review = commerce.reviews().create(CreateReview {
11//!     product_id: ProductId::new(),
12//!     customer_id: CustomerId::new(),
13//!     rating: 5,
14//!     title: Some("Excellent product!".into()),
15//!     body: Some("Works exactly as described.".into()),
16//!     ..Default::default()
17//! })?;
18//!
19//! println!("Review created with rating: {}", review.rating);
20//! # Ok::<(), stateset_embedded::CommerceError>(())
21//! ```
22
23use stateset_core::{
24    CreateReview, ProductId, Result, Review, ReviewFilter, ReviewId, ReviewSummary, UpdateReview,
25};
26use stateset_db::{Database, DatabaseCapability};
27use std::sync::Arc;
28
29/// Product review operations.
30pub struct Reviews {
31    db: Arc<dyn Database>,
32}
33
34impl std::fmt::Debug for Reviews {
35    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36        f.debug_struct("Reviews").finish_non_exhaustive()
37    }
38}
39
40impl Reviews {
41    pub(crate) fn new(db: Arc<dyn Database>) -> Self {
42        Self { db }
43    }
44
45    /// Whether reviews are supported by the active backend.
46    #[must_use]
47    pub fn is_supported(&self) -> bool {
48        self.db.supports_capability(DatabaseCapability::Reviews)
49    }
50
51    fn ensure_supported(&self) -> Result<()> {
52        self.db.ensure_capability(DatabaseCapability::Reviews)
53    }
54
55    /// Create a new product review.
56    ///
57    /// # Example
58    ///
59    /// ```rust,ignore
60    /// use stateset_embedded::{Commerce, CreateReview, ProductId, CustomerId};
61    ///
62    /// let commerce = Commerce::new("./store.db")?;
63    ///
64    /// let review = commerce.reviews().create(CreateReview {
65    ///     product_id: ProductId::new(),
66    ///     customer_id: CustomerId::new(),
67    ///     rating: 4,
68    ///     title: Some("Good value".into()),
69    ///     body: Some("Decent quality for the price.".into()),
70    ///     ..Default::default()
71    /// })?;
72    /// # Ok::<(), stateset_embedded::CommerceError>(())
73    /// ```
74    pub fn create(&self, input: CreateReview) -> Result<Review> {
75        self.ensure_supported()?;
76        self.db.reviews().create(input)
77    }
78
79    /// Get a review by ID.
80    pub fn get(&self, id: ReviewId) -> Result<Option<Review>> {
81        self.ensure_supported()?;
82        self.db.reviews().get(id)
83    }
84
85    /// Update a review.
86    pub fn update(&self, id: ReviewId, input: UpdateReview) -> Result<Review> {
87        self.ensure_supported()?;
88        self.db.reviews().update(id, input)
89    }
90
91    /// List reviews with optional filtering.
92    pub fn list(&self, filter: ReviewFilter) -> Result<Vec<Review>> {
93        self.ensure_supported()?;
94        self.db.reviews().list(filter)
95    }
96
97    /// Delete a review.
98    pub fn delete(&self, id: ReviewId) -> Result<()> {
99        self.ensure_supported()?;
100        self.db.reviews().delete(id)
101    }
102
103    /// Get aggregate review summary for a product.
104    ///
105    /// Returns average rating, total count, and rating distribution.
106    pub fn get_summary(&self, product_id: ProductId) -> Result<ReviewSummary> {
107        self.ensure_supported()?;
108        self.db.reviews().get_summary(product_id)
109    }
110
111    /// Mark a review as helpful (increment helpful count).
112    pub fn mark_helpful(&self, id: ReviewId) -> Result<()> {
113        self.ensure_supported()?;
114        self.db.reviews().mark_helpful(id)
115    }
116
117    /// Mark a review as reported (increment reported count).
118    pub fn mark_reported(&self, id: ReviewId) -> Result<()> {
119        self.ensure_supported()?;
120        self.db.reviews().mark_reported(id)
121    }
122}