sylvia_iot_broker/models/
network.rs

1//! Traits and structs for networks.
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 Network {
12    pub network_id: String,
13    pub code: String,
14    pub unit_id: Option<String>,
15    pub unit_code: Option<String>,
16    pub created_at: DateTime<Utc>,
17    pub modified_at: DateTime<Utc>,
18    pub host_uri: String,
19    pub name: String,
20    pub info: Map<String, Value>,
21}
22
23/// The sort keys for the list operation.
24pub enum SortKey {
25    CreatedAt,
26    ModifiedAt,
27    Code,
28    Name,
29}
30
31/// The sort condition for the list operation.
32pub struct SortCond {
33    pub key: SortKey,
34    pub asc: bool,
35}
36
37/// The list operation options.
38pub struct ListOptions<'a> {
39    /// The query conditions.
40    pub cond: &'a ListQueryCond<'a>,
41    /// The data offset.
42    pub offset: Option<u64>,
43    /// The maximum number to query.
44    pub limit: Option<u64>,
45    /// The sort conditions.
46    pub sort: Option<&'a [SortCond]>,
47    /// The maximum number items one time the `list()` returns.
48    ///
49    /// Use cursors until reaching `limit` or all data.
50    pub cursor_max: Option<u64>,
51}
52
53/// The query condition to get item(s).
54#[derive(Default)]
55pub struct QueryCond<'a> {
56    pub unit_id: Option<Option<&'a str>>,
57    pub network_id: Option<&'a str>,
58    pub code: Option<&'a str>,
59}
60
61/// The query condition for the list operation.
62#[derive(Default)]
63pub struct ListQueryCond<'a> {
64    /// To get networks of the specified unit.
65    pub unit_id: Option<Option<&'a str>>,
66    /// To get the specified network.
67    pub network_id: Option<&'a str>,
68    /// To get the specified network by code.
69    pub code: Option<&'a str>,
70    /// To get unit that their **code** contains the specified (partial) word.
71    pub code_contains: Option<&'a str>,
72    /// To get unit that their **name** contains the specified (partial) word.
73    pub name_contains: Option<&'a str>,
74}
75
76/// The query condition for the update operation.
77pub struct UpdateQueryCond<'a> {
78    /// The specified network.
79    pub network_id: &'a str,
80}
81
82/// The update fields by using [`Some`]s.
83#[derive(Default)]
84pub struct Updates<'a> {
85    pub modified_at: Option<DateTime<Utc>>,
86    pub host_uri: Option<&'a str>,
87    pub name: Option<&'a str>,
88    pub info: Option<&'a Map<String, Value>>,
89}
90
91/// Model operations.
92#[async_trait]
93pub trait NetworkModel: Sync {
94    /// To create and initialize the table/collection.
95    async fn init(&self) -> Result<(), Box<dyn StdError>>;
96
97    /// To get item count for the query condition.
98    ///
99    /// **Note**: this may take a long time.
100    async fn count(&self, cond: &ListQueryCond) -> Result<u64, Box<dyn StdError>>;
101
102    /// To get item list. The maximum number of returned items will be controlled by the
103    /// `cursor_max` of the list option.
104    ///
105    /// For the first time, `cursor` MUST use `None`. If one cursor is returned, it means that
106    /// there are more items to get. Use the returned cursor to get more data items.
107    ///
108    /// **Note**: using cursors is recommended to prevent exhausting memory.
109    async fn list(
110        &self,
111        opts: &ListOptions,
112        cursor: Option<Box<dyn Cursor>>,
113    ) -> Result<(Vec<Network>, Option<Box<dyn Cursor>>), Box<dyn StdError>>;
114
115    /// To get an item.
116    async fn get(&self, cond: &QueryCond) -> Result<Option<Network>, Box<dyn StdError>>;
117
118    /// To add an item.
119    async fn add(&self, network: &Network) -> Result<(), Box<dyn StdError>>;
120
121    /// To delete one or more items.
122    async fn del(&self, cond: &QueryCond) -> Result<(), Box<dyn StdError>>;
123
124    /// To update one or more items.
125    async fn update(
126        &self,
127        cond: &UpdateQueryCond,
128        updates: &Updates,
129    ) -> Result<(), Box<dyn StdError>>;
130}
131
132/// The operations for cursors.
133///
134/// All functions are private to let programs to pass them as arguments directly without any
135/// operation.
136#[async_trait]
137pub trait Cursor: Send {
138    async fn try_next(&mut self) -> Result<Option<Network>, Box<dyn StdError>>;
139
140    fn offset(&self) -> u64;
141}