sylvia_iot_data/models/
application_dldata.rs

1//! Traits and structs for application downlink data.
2
3use std::error::Error as StdError;
4
5use async_trait::async_trait;
6use chrono::{DateTime, Utc};
7use serde_json::{Map, Value};
8
9/// The item content.
10#[derive(Debug, PartialEq)]
11pub struct ApplicationDlData {
12    pub data_id: String,
13    pub proc: DateTime<Utc>,
14    pub resp: Option<DateTime<Utc>>,
15    pub status: i32,
16    pub unit_id: String,
17    pub device_id: Option<String>,
18    pub network_code: Option<String>,
19    pub network_addr: Option<String>,
20    pub profile: String,
21    pub data: String,
22    pub extension: Option<Map<String, Value>>,
23}
24
25/// The sort keys for the list operation.
26pub enum SortKey {
27    Proc,
28    Resp,
29    NetworkCode,
30    NetworkAddr,
31}
32
33/// The sort condition for the list operation.
34pub struct SortCond {
35    pub key: SortKey,
36    pub asc: bool,
37}
38
39/// The list operation options.
40pub struct ListOptions<'a> {
41    /// The query conditions.
42    pub cond: &'a ListQueryCond<'a>,
43    /// The data offset.
44    pub offset: Option<u64>,
45    /// The maximum number to query.
46    pub limit: Option<u64>,
47    /// The sort conditions.
48    pub sort: Option<&'a [SortCond]>,
49    /// The maximum number items one time the `list()` returns.
50    ///
51    /// Use cursors until reaching `limit` or all data.
52    pub cursor_max: Option<u64>,
53}
54
55/// The query condition to delete item(s).
56#[derive(Default)]
57pub struct QueryCond<'a> {
58    pub unit_id: Option<&'a str>,
59    pub device_id: Option<&'a str>,
60    pub network_code: Option<&'a str>,
61    pub network_addr: Option<&'a str>,
62    pub proc_gte: Option<DateTime<Utc>>,
63    pub proc_lte: Option<DateTime<Utc>>,
64}
65
66/// The query condition for the list operation.
67#[derive(Default)]
68pub struct ListQueryCond<'a> {
69    /// To get the specified unit.
70    pub unit_id: Option<&'a str>,
71    /// To get the specified device.
72    pub device_id: Option<&'a str>,
73    /// To get the specified device's network code.
74    pub network_code: Option<&'a str>,
75    /// To get the specified device's network address.
76    pub network_addr: Option<&'a str>,
77    /// To get the specified device/data profile.
78    pub profile: Option<&'a str>,
79    /// To get data greater than and equal to the specified `proc` time.
80    pub proc_gte: Option<DateTime<Utc>>,
81    /// To get data less than and equal to the specified `proc` time.
82    pub proc_lte: Option<DateTime<Utc>>,
83    /// To get data greater than and equal to the specified `resp` time.
84    pub resp_gte: Option<DateTime<Utc>>,
85    /// To get data less than and equal to the specified `resp` time.
86    pub resp_lte: Option<DateTime<Utc>>,
87}
88
89/// The query condition for the update operation.
90pub struct UpdateQueryCond<'a> {
91    /// The specified data.
92    pub data_id: &'a str,
93}
94
95/// The update fields.
96pub struct Updates {
97    pub resp: DateTime<Utc>,
98    /// The status will be changed for the following cases:
99    /// - Zero and positive value changes non-zero status data.
100    /// - Negative value changes smaller status value data.
101    pub status: i32,
102}
103
104/// Model operations.
105#[async_trait]
106pub trait ApplicationDlDataModel: Sync {
107    /// To create and initialize the table/collection.
108    async fn init(&self) -> Result<(), Box<dyn StdError>>;
109
110    /// To get item count for the query condition.
111    ///
112    /// **Note**: this may take a long time.
113    async fn count(&self, cond: &ListQueryCond) -> Result<u64, Box<dyn StdError>>;
114
115    /// To get item list. The maximum number of returned items will be controlled by the
116    /// `cursor_max` of the list option.
117    ///
118    /// For the first time, `cursor` MUST use `None`. If one cursor is returned, it means that
119    /// there are more items to get. Use the returned cursor to get more data items.
120    ///
121    /// **Note**: using cursors is recommended to prevent exhausting memory.
122    async fn list(
123        &self,
124        opts: &ListOptions,
125        cursor: Option<Box<dyn Cursor>>,
126    ) -> Result<(Vec<ApplicationDlData>, Option<Box<dyn Cursor>>), Box<dyn StdError>>;
127
128    /// To add an item.
129    async fn add(&self, data: &ApplicationDlData) -> Result<(), Box<dyn StdError>>;
130
131    /// To delete one or more items.
132    async fn del(&self, cond: &QueryCond) -> Result<(), Box<dyn StdError>>;
133
134    /// To update one or more items.
135    async fn update(
136        &self,
137        cond: &UpdateQueryCond,
138        updates: &Updates,
139    ) -> Result<(), Box<dyn StdError>>;
140}
141
142/// The operations for cursors.
143///
144/// All functions are private to let programs to pass them as arguments directly without any
145/// operation.
146#[async_trait]
147pub trait Cursor: Send {
148    async fn try_next(&mut self) -> Result<Option<ApplicationDlData>, Box<dyn StdError>>;
149
150    fn offset(&self) -> u64;
151}
152
153/// The expiration time of the data in seconds.
154pub const EXPIRES: i64 = 100 * 86400;