news_flash/models/
offline_action.rs1use diesel::{
2 backend::Backend,
3 deserialize::{self, FromSql},
4 serialize::{self, IsNull, Output, ToSql},
5 sql_types::Integer,
6 sqlite::Sqlite,
7};
8use serde::{Deserialize, Serialize};
9
10use crate::schema::offline_actions;
11
12use super::{ArticleID, TagID};
13
14#[derive(Eq, PartialEq, Copy, Clone, Debug, AsExpression, FromSqlRow, Serialize, Deserialize, Hash)]
15#[diesel(sql_type = Integer)]
16pub enum OfflineActionType {
17 Read,
18 Unread,
19 Mark,
20 Unmark,
21 Tag,
22 Untag,
23}
24
25impl From<i32> for OfflineActionType {
26 fn from(value: i32) -> Self {
27 match value {
28 0 => Self::Read,
29 1 => Self::Unread,
30 2 => Self::Mark,
31 3 => Self::Unmark,
32 4 => Self::Tag,
33 5 => Self::Untag,
34
35 _ => Self::Read,
36 }
37 }
38}
39
40impl FromSql<Integer, Sqlite> for OfflineActionType {
41 fn from_sql(bytes: <Sqlite as Backend>::RawValue<'_>) -> deserialize::Result<Self> {
42 let int = i32::from_sql(bytes)?;
43 Ok(OfflineActionType::from(int))
44 }
45}
46
47impl ToSql<Integer, Sqlite> for OfflineActionType {
48 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> serialize::Result {
49 out.set_value(*self as i32);
50 Ok(IsNull::No)
51 }
52}
53
54#[derive(Identifiable, Insertable, Queryable, Clone, Eq, PartialEq, Debug)]
55#[diesel(primary_key(action_type, article_id, tag_id))]
56#[diesel(table_name = offline_actions)]
57#[diesel(check_for_backend(SQLite))]
58pub struct OfflineAction {
59 pub action_type: OfflineActionType,
60 pub article_id: ArticleID,
61 pub tag_id: Option<TagID>,
62}