1use crate::client::{Auth, Client};
2use crate::httpc::Httpc;
3use anyhow::Result;
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Deserialize, Clone, Serialize)]
7#[serde(rename_all = "camelCase")]
8pub struct Field {
9 pub system: bool,
10 pub id: String,
11 pub name: String,
12 pub r#type: String,
13 pub required: bool,
14 pub unique: bool,
15}
16
17#[derive(Debug, Clone, Deserialize, Serialize)]
18#[serde(rename_all = "camelCase")]
19pub struct FieldDeclaration<'a> {
20 pub name: &'a str,
21 pub r#type: &'a str,
22 pub required: bool,
23}
24
25#[derive(Debug, Deserialize)]
26#[serde(rename_all = "camelCase")]
27pub struct CollectionList {
28 pub page: i32,
29 pub per_page: i32,
30 pub total_items: i32,
31 pub items: Vec<Collection>,
32}
33
34#[derive(Debug, Deserialize, Clone)]
35#[serde(rename_all = "camelCase")]
36pub struct Collection {
37 pub id: String,
38 pub created: String,
39 pub r#type: String,
40 pub updated: String,
41 pub name: String,
42 pub schema: Vec<Field>,
43}
44
45#[derive(Clone, Debug)]
46pub struct CollectionsManager<'a> {
47 pub client: &'a Client<Auth>,
48}
49
50#[derive(Debug, Clone, Serialize)]
52#[serde(rename_all = "camelCase")]
53pub struct CollectionDetails<'a> {
54 pub id: Option<&'a str>,
55 pub name: Option<&'a str>,
56 pub r#type: Option<&'a str>,
57 pub schema: Vec<FieldDeclaration<'a>>,
58 pub system: bool,
59 pub list_rule: Option<String>,
60 pub view_rule: Option<String>,
61 pub create_rule: Option<String>,
62 pub update_rule: Option<String>,
63 pub delete_rule: Option<String>,
64 pub indexes: Vec<String>,
65}
66
67#[derive(Debug, Clone)]
68pub struct CollectionCreateRequestBuilder<'a> {
69 pub client: &'a Client<Auth>,
70 pub collection_name: &'a str,
71 pub collection_details: Option<CollectionDetails<'a>>,
72}
73
74#[derive(Clone, Debug)]
75pub struct CollectionViewRequestBuilder<'a> {
76 pub client: &'a Client<Auth>,
77 pub name: &'a str,
78}
79
80#[derive(Clone, Debug)]
81pub struct CollectionListRequestBuilder<'a> {
82 pub client: &'a Client<Auth>,
83 pub filter: Option<String>,
84 pub sort: Option<String>,
85 pub per_page: i32,
86 pub page: i32,
87}
88
89impl<'a> CollectionListRequestBuilder<'a> {
90 pub fn call(&self) -> Result<CollectionList> {
91 let url = format!("{}/api/collections", self.client.base_url);
92 let mut build_opts: Vec<(&str, &str)> = Vec::new();
93
94 if let Some(filter_opts) = &self.filter {
95 build_opts.push(("filter", filter_opts))
96 }
97 if let Some(sort_opts) = &self.sort {
98 build_opts.push(("sort", sort_opts))
99 }
100 let per_page_opts = self.per_page.to_string();
101 let page_opts = self.page.to_string();
102 build_opts.push(("per_page", per_page_opts.as_str()));
103 build_opts.push(("page", page_opts.as_str()));
104
105 match Httpc::get(self.client, &url, Some(build_opts)) {
106 Ok(result) => {
107 let response = result.into_json::<CollectionList>()?;
108 Ok(response)
109 }
110 Err(e) => Err(e),
111 }
112 }
113
114 pub fn filter(&self, filter_opts: String) -> Self {
115 Self {
116 filter: Some(filter_opts),
117 ..self.clone()
118 }
119 }
120
121 pub fn per_page(&self, per_page_count: i32) -> Self {
122 Self {
123 per_page: per_page_count,
124 ..self.clone()
125 }
126 }
127
128 pub fn page(&self, page_count: i32) -> Self {
129 Self {
130 page: page_count,
131 ..self.clone()
132 }
133 }
134
135 pub fn sort(&self, sort_opts: String) -> Self {
136 Self {
137 sort: Some(sort_opts),
138 ..self.clone()
139 }
140 }
141}
142
143impl<'a> CollectionsManager<'a> {
144 pub fn view(&self, name: &'a str) -> CollectionViewRequestBuilder {
145 CollectionViewRequestBuilder {
146 client: self.client,
147 name,
148 }
149 }
150
151 pub fn create(&self, name: &'a str) -> CollectionCreateRequestBuilder {
152 CollectionCreateRequestBuilder {
153 client: self.client,
154 collection_details: None,
155 collection_name: name,
156 }
157 }
158
159 pub fn list(&self) -> CollectionListRequestBuilder {
160 CollectionListRequestBuilder {
161 client: self.client,
162 filter: None,
163 sort: None,
164 per_page: 100,
165 page: 1,
166 }
167 }
168}
169
170impl<'a> CollectionViewRequestBuilder<'a> {
171 pub fn call(&self) -> Result<Collection> {
172 let url = format!("{}/api/collections/{}", self.client.base_url, self.name);
173 match Httpc::get(self.client, &url, None) {
174 Ok(result) => {
175 let response = result.into_json::<Collection>()?;
176 Ok(response)
177 }
178 Err(e) => Err(e),
179 }
180 }
181}