1use clap::ValueEnum;
3use serde::{Deserialize, Serialize};
4use std::fmt;
5
6#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ValueEnum)]
7#[serde(rename_all = "lowercase")]
8pub enum FeedbackLabel {
9 Good,
10 Bad,
11 Interesting,
12 Bug,
13 Regression,
14}
15
16impl FeedbackLabel {
17 pub fn from_str_opt(s: &str) -> Option<Self> {
18 match s {
19 "good" => Some(Self::Good),
20 "bad" => Some(Self::Bad),
21 "interesting" => Some(Self::Interesting),
22 "bug" => Some(Self::Bug),
23 "regression" => Some(Self::Regression),
24 _ => None,
25 }
26 }
27
28 pub fn to_db_str(&self) -> &str {
29 match self {
30 Self::Good => "good",
31 Self::Bad => "bad",
32 Self::Interesting => "interesting",
33 Self::Bug => "bug",
34 Self::Regression => "regression",
35 }
36 }
37}
38
39impl fmt::Display for FeedbackLabel {
40 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41 write!(f, "{}", self.to_db_str())
42 }
43}
44
45#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
47pub struct FeedbackScore(pub u8);
48
49impl FeedbackScore {
50 pub fn new(v: u8) -> Option<Self> {
52 if (1..=5).contains(&v) {
53 Some(Self(v))
54 } else {
55 None
56 }
57 }
58}
59
60#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
61pub struct FeedbackRecord {
62 pub id: String,
63 pub session_id: String,
64 pub score: Option<FeedbackScore>,
65 pub label: Option<FeedbackLabel>,
66 pub note: Option<String>,
67 pub created_at_ms: u64,
68}