Skip to main content

vn_core/model/
trait.rs

1use super::{QueryField, SortQueryBy};
2use crate::{impl_id_newtype, impl_into_field_set};
3use regex::Regex;
4use serde::{Deserialize, Serialize};
5use std::sync::{Arc, LazyLock};
6use strum::{Display, EnumString, VariantArray};
7
8static ID_REGEX: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"^i\d+$").unwrap());
9
10#[remain::sorted]
11#[derive(Clone, Debug, Deserialize, Serialize)]
12#[cfg_attr(feature = "specta", derive(specta::Type))]
13pub struct Trait {
14  pub aliases: Option<Vec<String>>,
15  pub applicable: Option<bool>,
16  pub char_count: Option<u32>,
17  pub description: Option<String>,
18  pub group_id: Option<TraitId>,
19  pub group_name: Option<String>,
20  pub id: TraitId,
21  pub name: Option<String>,
22  pub searchable: Option<bool>,
23  pub sexual: Option<bool>,
24}
25
26impl From<Trait> for TraitId {
27  fn from(t: Trait) -> Self {
28    t.id
29  }
30}
31
32#[derive(
33  Debug,
34  Deserialize,
35  Serialize,
36  PartialEq,
37  Eq,
38  PartialOrd,
39  Ord,
40  Hash,
41  derive_more::Display,
42  derive_more::Into,
43)]
44#[cfg_attr(feature = "specta", derive(specta::Type))]
45pub struct TraitId(#[cfg_attr(feature = "specta", specta(type = String))] Arc<str>);
46
47impl TraitId {
48  pub const PREFIX: char = 'i';
49}
50
51impl_id_newtype!(Trait, TraitId, ID_REGEX);
52
53#[non_exhaustive]
54#[remain::sorted]
55#[derive(Clone, Copy, Debug, Deserialize, Serialize, Display, EnumString, VariantArray)]
56#[cfg_attr(feature = "specta", derive(specta::Type))]
57pub enum TraitField {
58  #[serde(rename = "aliases")]
59  #[strum(serialize = "aliases")]
60  Aliases,
61
62  #[serde(rename = "applicable")]
63  #[strum(serialize = "applicable")]
64  Applicable,
65
66  #[serde(rename = "char_count")]
67  #[strum(serialize = "char_count")]
68  CharCount,
69
70  #[serde(rename = "description")]
71  #[strum(serialize = "description")]
72  Description,
73
74  #[serde(rename = "group_id")]
75  #[strum(serialize = "group_id")]
76  GroupId,
77
78  #[serde(rename = "group_name")]
79  #[strum(serialize = "group_name")]
80  GroupName,
81
82  #[serde(rename = "id")]
83  #[strum(serialize = "id")]
84  Id,
85
86  #[serde(rename = "name")]
87  #[strum(serialize = "name")]
88  Name,
89
90  #[serde(rename = "searchable")]
91  #[strum(serialize = "searchable")]
92  Searchable,
93
94  #[serde(rename = "sexual")]
95  #[strum(serialize = "sexual")]
96  Sexual,
97}
98
99impl QueryField for TraitField {}
100
101impl_into_field_set!(TraitField);
102
103#[non_exhaustive]
104#[remain::sorted]
105#[derive(Clone, Copy, Debug, Deserialize, Serialize, Display, EnumString)]
106#[cfg_attr(feature = "specta", derive(specta::Type))]
107pub enum SortTraitBy {
108  #[serde(rename = "char_count")]
109  #[strum(serialize = "char_count")]
110  CharCount,
111
112  #[serde(rename = "id")]
113  #[strum(serialize = "id")]
114  Id,
115
116  #[serde(rename = "name")]
117  #[strum(serialize = "name")]
118  Name,
119
120  #[serde(rename = "searchrank")]
121  #[strum(serialize = "searchrank")]
122  SearchRank,
123}
124
125impl SortQueryBy for SortTraitBy {}