1use serde::{Deserialize, Serialize};
11use serde_with::skip_serializing_none;
12
13use cloudillo_core::prelude::*;
14use cloudillo_types::types::serialize_timestamp_iso;
15
16#[skip_serializing_none]
21#[derive(Debug, Clone, Default, Serialize, Deserialize)]
22#[serde(rename_all = "camelCase")]
23pub struct ContactName {
24 pub given: Option<String>,
25 pub family: Option<String>,
26 pub additional: Option<String>,
27 pub prefix: Option<String>,
28 pub suffix: Option<String>,
29}
30
31#[skip_serializing_none]
33#[derive(Debug, Clone, Default, Serialize, Deserialize)]
34#[serde(rename_all = "camelCase")]
35pub struct TypedValue {
36 pub value: String,
37 #[serde(default, skip_serializing_if = "Vec::is_empty")]
38 pub r#type: Vec<String>,
39 pub pref: Option<u8>,
40}
41
42#[skip_serializing_none]
48#[derive(Debug, Clone, Serialize)]
49#[serde(rename_all = "camelCase")]
50pub struct ProfileOverlay {
51 pub id_tag: String,
52 pub name: Option<String>,
53 pub r#type: Option<String>,
54 pub profile_pic: Option<String>,
55 pub status: Option<cloudillo_types::meta_adapter::ProfileStatus>,
56 pub connected: Option<bool>,
57 pub following: Option<bool>,
58}
59
60#[skip_serializing_none]
68#[derive(Debug, Clone, Default, Deserialize)]
69#[serde(rename_all = "camelCase")]
70pub struct ContactInput {
71 pub uid: Option<String>,
72 #[serde(rename = "fn")]
73 pub formatted_name: Option<String>,
74 pub n: Option<ContactName>,
75 #[serde(default)]
76 pub emails: Vec<TypedValue>,
77 #[serde(default)]
78 pub phones: Vec<TypedValue>,
79 pub org: Option<String>,
80 pub title: Option<String>,
81 pub note: Option<String>,
82 pub photo: Option<String>,
83 pub profile_id_tag: Option<String>,
84}
85
86#[derive(Debug, Default, Deserialize)]
89#[serde(rename_all = "camelCase")]
90pub struct ContactPatch {
91 #[serde(default, rename = "fn")]
92 pub formatted_name: Patch<String>,
93 #[serde(default)]
94 pub n: Patch<ContactName>,
95 #[serde(default)]
96 pub emails: Patch<Vec<TypedValue>>,
97 #[serde(default)]
98 pub phones: Patch<Vec<TypedValue>>,
99 #[serde(default)]
100 pub org: Patch<String>,
101 #[serde(default)]
102 pub title: Patch<String>,
103 #[serde(default)]
104 pub note: Patch<String>,
105 #[serde(default)]
106 pub photo: Patch<String>,
107 #[serde(default)]
108 pub profile_id_tag: Patch<String>,
109}
110
111#[skip_serializing_none]
116#[derive(Debug, Clone, Serialize)]
117#[serde(rename_all = "camelCase")]
118pub struct ContactOutput {
119 pub c_id: u64,
120 pub ab_id: u64,
121 pub uid: String,
122 pub etag: String,
123 #[serde(rename = "fn")]
124 pub formatted_name: Option<String>,
125 pub n: Option<ContactName>,
126 #[serde(default, skip_serializing_if = "Vec::is_empty")]
127 pub emails: Vec<TypedValue>,
128 #[serde(default, skip_serializing_if = "Vec::is_empty")]
129 pub phones: Vec<TypedValue>,
130 pub org: Option<String>,
131 pub title: Option<String>,
132 pub note: Option<String>,
133 pub photo: Option<String>,
134 pub profile_id_tag: Option<String>,
135 pub profile: Option<ProfileOverlay>,
137 pub parse_error: Option<String>,
140 #[serde(serialize_with = "serialize_timestamp_iso")]
141 pub created_at: Timestamp,
142 #[serde(serialize_with = "serialize_timestamp_iso")]
143 pub updated_at: Timestamp,
144}
145
146#[skip_serializing_none]
148#[derive(Debug, Clone, Serialize)]
149#[serde(rename_all = "camelCase")]
150pub struct ContactListItem {
151 pub c_id: u64,
152 pub ab_id: u64,
153 pub uid: String,
154 pub etag: String,
155 #[serde(rename = "fn")]
156 pub formatted_name: Option<String>,
157 pub email: Option<String>,
158 pub tel: Option<String>,
159 pub org: Option<String>,
160 pub photo: Option<String>,
161 pub profile_id_tag: Option<String>,
162 pub profile: Option<ProfileOverlay>,
163 #[serde(serialize_with = "serialize_timestamp_iso")]
164 pub updated_at: Timestamp,
165}
166
167#[skip_serializing_none]
171#[derive(Debug, Clone, Serialize)]
172#[serde(rename_all = "camelCase")]
173pub struct AddressBookOutput {
174 pub ab_id: u64,
175 pub name: String,
176 pub description: Option<String>,
177 pub ctag: String,
178 #[serde(serialize_with = "serialize_timestamp_iso")]
179 pub created_at: Timestamp,
180 #[serde(serialize_with = "serialize_timestamp_iso")]
181 pub updated_at: Timestamp,
182}
183
184#[skip_serializing_none]
185#[derive(Debug, Default, Deserialize)]
186#[serde(rename_all = "camelCase")]
187pub struct AddressBookCreate {
188 pub name: String,
189 pub description: Option<String>,
190}
191
192#[derive(Debug, Default, Deserialize)]
193#[serde(rename_all = "camelCase")]
194pub struct AddressBookPatch {
195 #[serde(default)]
196 pub name: Patch<String>,
197 #[serde(default)]
198 pub description: Patch<String>,
199}
200
201#[derive(Debug, Default, Deserialize)]
202#[serde(rename_all = "camelCase")]
203pub struct ListContactsQuery {
204 pub q: Option<String>,
205 pub cursor: Option<String>,
206 pub limit: Option<u32>,
207}
208
209#[derive(Debug, Clone, Copy, Deserialize, Default, PartialEq, Eq)]
214#[serde(rename_all = "kebab-case")]
215pub enum ImportConflictMode {
216 #[default]
218 Skip,
219 Replace,
221 Add,
223}
224
225#[derive(Debug, Default, Deserialize)]
226#[serde(rename_all = "camelCase")]
227pub struct ImportContactsQuery {
228 #[serde(default)]
229 pub conflict: Option<ImportConflictMode>,
230}
231
232#[derive(Debug, Default, Serialize)]
233#[serde(rename_all = "camelCase")]
234pub struct ImportContactsError {
235 pub index: u32,
237 pub uid: Option<String>,
238 pub message: String,
239}
240
241#[derive(Debug, Default, Serialize)]
242#[serde(rename_all = "camelCase")]
243pub struct ImportContactsResult {
244 pub total: u32,
246 pub imported: u32,
248 pub updated: u32,
250 pub skipped: u32,
252 pub errors: Vec<ImportContactsError>,
254}
255
256