Skip to main content

news_flash/models/
offline_action.rs

1use 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}