1use diesel::backend::Backend;
2use diesel::deserialize::{self, FromSql};
3use diesel::serialize::{self, IsNull, Output, ToSql};
4use diesel::sql_types::Text;
5use diesel::sqlite::Sqlite;
6use once_cell::sync::Lazy;
7use serde::{Deserialize, Serialize};
8use std::sync::Arc;
9use std::{fmt, str};
10
11#[derive(Eq, PartialEq, Hash, Clone, Debug, Serialize, Deserialize, AsExpression, FromSqlRow)]
12#[diesel(sql_type = Text)]
13pub struct ArticleID(Arc<String>);
14
15impl ArticleID {
16 pub fn new(id: &str) -> Self {
17 Self::from_owned(id.into())
18 }
19
20 pub fn from_owned(id: String) -> Self {
21 ArticleID(Arc::new(id))
22 }
23
24 pub fn as_str(&self) -> &str {
25 &self.0
26 }
27}
28
29impl fmt::Display for ArticleID {
30 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31 write!(f, "{}", self.0)
32 }
33}
34
35impl FromSql<Text, Sqlite> for ArticleID {
36 fn from_sql(bytes: <Sqlite as Backend>::RawValue<'_>) -> deserialize::Result<Self> {
37 let bytes = <Vec<u8>>::from_sql(bytes)?;
38 let string = str::from_utf8(&bytes)?;
39 Ok(ArticleID::new(string))
40 }
41}
42
43impl ToSql<Text, Sqlite> for ArticleID {
44 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> serialize::Result {
45 out.set_value(self.as_str());
46 Ok(IsNull::No)
47 }
48}
49
50#[derive(Eq, PartialEq, Hash, Clone, Debug, Serialize, Deserialize, AsExpression, FromSqlRow)]
53#[diesel(sql_type = Text)]
54pub struct FeedID(Arc<String>);
55impl FeedID {
56 pub fn new(id: &str) -> Self {
57 Self::from_owned(id.into())
58 }
59
60 pub fn from_owned(id: String) -> Self {
61 FeedID(Arc::new(id))
62 }
63
64 pub fn as_str(&self) -> &str {
65 &self.0
66 }
67}
68
69impl fmt::Display for FeedID {
70 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71 write!(f, "{}", self.0)
72 }
73}
74
75impl FromSql<Text, Sqlite> for FeedID {
76 fn from_sql(bytes: <Sqlite as Backend>::RawValue<'_>) -> deserialize::Result<Self> {
77 let bytes = <Vec<u8>>::from_sql(bytes)?;
78 let string = str::from_utf8(&bytes)?;
79 Ok(FeedID::new(string))
80 }
81}
82
83impl ToSql<Text, Sqlite> for FeedID {
84 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> serialize::Result {
85 out.set_value(self.as_str());
86 Ok(IsNull::No)
87 }
88}
89
90pub static NEWSFLASH_TOPLEVEL: Lazy<CategoryID> = Lazy::new(|| CategoryID::new("NewsFlash.Toplevel"));
93
94#[derive(Eq, PartialEq, Hash, Clone, Debug, Serialize, Deserialize, AsExpression, FromSqlRow)]
95#[diesel(sql_type = Text)]
96pub struct CategoryID(Arc<String>);
97impl CategoryID {
98 pub fn new(id: &str) -> Self {
99 Self::from_owned(id.into())
100 }
101
102 pub fn from_owned(id: String) -> Self {
103 CategoryID(Arc::new(id))
104 }
105
106 pub fn as_str(&self) -> &str {
107 &self.0
108 }
109}
110
111impl fmt::Display for CategoryID {
112 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
113 write!(f, "{}", self.0)
114 }
115}
116
117impl FromSql<Text, Sqlite> for CategoryID {
118 fn from_sql(bytes: <Sqlite as Backend>::RawValue<'_>) -> deserialize::Result<Self> {
119 let bytes = <Vec<u8>>::from_sql(bytes)?;
120 let string = str::from_utf8(&bytes)?;
121 Ok(CategoryID::new(string))
122 }
123}
124
125impl ToSql<Text, Sqlite> for CategoryID {
126 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> serialize::Result {
127 out.set_value(self.as_str());
128 Ok(IsNull::No)
129 }
130}
131
132#[derive(Eq, PartialEq, Hash, Clone, Debug, Serialize, Deserialize, AsExpression, FromSqlRow)]
135#[diesel(sql_type = Text)]
136pub struct TagID(Arc<String>);
137impl TagID {
138 pub fn new(id: &str) -> Self {
139 Self::from_owned(id.into())
140 }
141
142 pub fn from_owned(id: String) -> Self {
143 TagID(Arc::new(id))
144 }
145
146 pub fn as_str(&self) -> &str {
147 &self.0
148 }
149}
150
151impl fmt::Display for TagID {
152 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
153 write!(f, "{}", self.0)
154 }
155}
156
157impl FromSql<Text, Sqlite> for TagID {
158 fn from_sql(bytes: <Sqlite as Backend>::RawValue<'_>) -> deserialize::Result<Self> {
159 let bytes = <Vec<u8>>::from_sql(bytes)?;
160 let string = str::from_utf8(&bytes)?;
161 Ok(TagID::new(string))
162 }
163}
164
165impl ToSql<Text, Sqlite> for TagID {
166 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> serialize::Result {
167 out.set_value(self.as_str());
168 Ok(IsNull::No)
169 }
170}
171
172#[derive(Eq, PartialEq, Hash, Clone, Debug, Serialize, Deserialize, AsExpression, FromSqlRow)]
175#[diesel(sql_type = Text)]
176pub struct PluginID(Arc<String>);
177impl PluginID {
178 pub fn new(id: &str) -> Self {
179 Self::from_owned(id.into())
180 }
181
182 pub fn from_owned(id: String) -> Self {
183 PluginID(Arc::new(id))
184 }
185
186 pub fn as_str(&self) -> &str {
187 &self.0
188 }
189}
190
191impl fmt::Display for PluginID {
192 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
193 write!(f, "{}", self.0)
194 }
195}
196
197impl FromSql<Text, Sqlite> for PluginID {
198 fn from_sql(bytes: <Sqlite as Backend>::RawValue<'_>) -> deserialize::Result<Self> {
199 let bytes = <Vec<u8>>::from_sql(bytes)?;
200 let string = str::from_utf8(&bytes)?;
201 Ok(PluginID::new(string))
202 }
203}
204
205impl ToSql<Text, Sqlite> for PluginID {
206 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> serialize::Result {
207 out.set_value(self.as_str());
208 Ok(IsNull::No)
209 }
210}