1use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8
9#[derive(Debug, Clone, Deserialize, Serialize)]
17pub struct DescribeGlobalResult {
18 pub encoding: String,
20
21 #[serde(rename = "maxBatchSize")]
23 pub max_batch_size: u32,
24
25 pub sobjects: Vec<SObjectBasicInfo>,
27}
28
29#[derive(Debug, Clone, Deserialize, Serialize)]
31pub struct SObjectBasicInfo {
32 pub name: String,
33 pub label: String,
34 #[serde(rename = "labelPlural")]
35 pub label_plural: String,
36 #[serde(rename = "keyPrefix")]
37 pub key_prefix: Option<String>,
38 pub custom: bool,
39 pub queryable: bool,
40 pub createable: bool,
41 pub updateable: bool,
42 pub deletable: bool,
43 pub searchable: bool,
44 pub retrieveable: bool,
45 #[serde(rename = "customSetting")]
46 pub custom_setting: Option<bool>,
47 #[serde(rename = "deprecatedAndHidden")]
48 pub deprecated_and_hidden: Option<bool>,
49 #[serde(rename = "feedEnabled")]
50 pub feed_enabled: Option<bool>,
51 #[serde(rename = "mruEnabled")]
52 pub mru_enabled: Option<bool>,
53 pub layoutable: Option<bool>,
54 pub triggerable: Option<bool>,
55 pub replicateable: Option<bool>,
56 pub urls: Option<HashMap<String, String>>,
57}
58
59#[derive(Debug, Clone, Deserialize, Serialize)]
68pub struct DescribeSObjectResult {
69 pub name: String,
71 pub label: String,
72 #[serde(rename = "labelPlural")]
73 pub label_plural: Option<String>,
74 #[serde(rename = "keyPrefix")]
75 pub key_prefix: Option<String>,
76 pub custom: bool,
77 #[serde(rename = "customSetting")]
78 pub custom_setting: Option<bool>,
79
80 #[serde(default)]
82 pub createable: bool,
83 #[serde(default)]
84 pub deletable: bool,
85 #[serde(default)]
86 pub queryable: bool,
87 #[serde(default)]
88 pub retrieveable: bool,
89 #[serde(default)]
90 pub searchable: bool,
91 #[serde(default)]
92 pub updateable: bool,
93 pub undeletable: Option<bool>,
94 pub mergeable: Option<bool>,
95 pub replicateable: Option<bool>,
96
97 pub activateable: Option<bool>,
99 #[serde(rename = "compactLayoutable")]
100 pub compact_layoutable: Option<bool>,
101 #[serde(rename = "deepCloneable")]
102 pub deep_cloneable: Option<bool>,
103 pub layoutable: Option<bool>,
104 pub listviewable: Option<bool>,
105 #[serde(rename = "lookupLayoutable")]
106 pub lookup_layoutable: Option<bool>,
107 #[serde(rename = "searchLayoutable")]
108 pub search_layoutable: Option<bool>,
109 pub triggerable: Option<bool>,
110 #[serde(rename = "mruEnabled")]
111 pub mru_enabled: Option<bool>,
112 #[serde(rename = "feedEnabled")]
113 pub feed_enabled: Option<bool>,
114
115 #[serde(rename = "childRelationships", default)]
117 pub child_relationships: Vec<ChildRelationship>,
118 pub fields: Vec<FieldDescribe>,
119
120 #[serde(rename = "recordTypeInfos", default)]
122 pub record_type_infos: Vec<RecordTypeInfo>,
123 #[serde(rename = "namedLayoutInfos", default)]
124 pub named_layout_infos: Vec<NamedLayoutInfo>,
125
126 #[serde(rename = "hasSubtypes")]
128 pub has_subtypes: Option<bool>,
129 #[serde(rename = "isInterface")]
130 pub is_interface: Option<bool>,
131 #[serde(rename = "isSubtype")]
132 pub is_subtype: Option<bool>,
133 #[serde(rename = "defaultImplementation")]
134 pub default_implementation: Option<String>,
135 #[serde(rename = "extendedBy")]
136 pub extended_by: Option<String>,
137 #[serde(rename = "extendsInterfaces")]
138 pub extends_interfaces: Option<String>,
139 #[serde(rename = "implementedBy")]
140 pub implemented_by: Option<String>,
141 #[serde(rename = "implementsInterfaces")]
142 pub implements_interfaces: Option<String>,
143
144 #[serde(rename = "deprecatedAndHidden")]
146 pub deprecated_and_hidden: Option<bool>,
147 #[serde(rename = "sobjectDescribeOption")]
148 pub sobject_describe_option: Option<String>,
149 #[serde(rename = "networkScopeFieldName")]
150 pub network_scope_field_name: Option<String>,
151 #[serde(default)]
152 pub urls: HashMap<String, String>,
153 #[serde(rename = "supportedScopes", default)]
154 pub supported_scopes: Vec<ScopeInfo>,
155 #[serde(rename = "actionOverrides", default)]
156 pub action_overrides: Vec<ActionOverride>,
157}
158
159#[derive(Debug, Clone, Deserialize, Serialize)]
161pub struct ChildRelationship {
162 #[serde(rename = "childSObject")]
163 pub child_sobject: String,
164 pub field: String,
165 #[serde(rename = "relationshipName")]
166 pub relationship_name: Option<String>,
167 #[serde(rename = "deprecatedAndHidden")]
168 pub deprecated_and_hidden: Option<bool>,
169 #[serde(rename = "cascadeDelete")]
170 pub cascade_delete: Option<bool>,
171 #[serde(rename = "restrictedDelete")]
172 pub restricted_delete: Option<bool>,
173 #[serde(rename = "junctionIdListNames", default)]
174 pub junction_id_list_names: Vec<String>,
175 #[serde(rename = "junctionReferenceTo", default)]
176 pub junction_reference_to: Vec<String>,
177}
178
179#[derive(Debug, Clone, Deserialize, Serialize)]
181pub struct RecordTypeInfo {
182 pub name: String,
183 #[serde(rename = "recordTypeId")]
184 pub record_type_id: String,
185 #[serde(rename = "developerName")]
186 pub developer_name: Option<String>,
187 pub active: bool,
188 pub available: bool,
189 #[serde(rename = "defaultRecordTypeMapping")]
190 pub default_record_type_mapping: bool,
191 pub master: Option<bool>,
192}
193
194#[derive(Debug, Clone, Deserialize, Serialize)]
196pub struct NamedLayoutInfo {
197 pub name: String,
198}
199
200#[derive(Debug, Clone, Deserialize, Serialize)]
202pub struct ScopeInfo {
203 pub name: String,
204 pub label: String,
205}
206
207#[derive(Debug, Clone, Deserialize, Serialize)]
209pub struct ActionOverride {
210 #[serde(rename = "formFactor")]
211 pub form_factor: Option<String>,
212 #[serde(rename = "isAvailableInTouch")]
213 pub is_available_in_touch: Option<bool>,
214 pub name: String,
215 #[serde(rename = "pageId")]
216 pub page_id: Option<String>,
217 pub url: Option<String>,
218}
219
220#[derive(Debug, Clone, Deserialize, Serialize)]
229pub struct FieldDescribe {
230 pub name: String,
232 pub label: String,
233 #[serde(rename = "type")]
234 pub field_type: String,
235 #[serde(rename = "soapType")]
236 pub soap_type: Option<String>,
237 pub custom: Option<bool>,
238
239 pub length: Option<i32>,
241 #[serde(rename = "byteLength")]
242 pub byte_length: Option<i32>,
243 pub precision: Option<i32>,
244 pub scale: Option<i32>,
245 pub digits: Option<i32>,
246
247 #[serde(default)]
249 pub createable: bool,
250 #[serde(default)]
251 pub updateable: bool,
252 #[serde(default)]
253 pub nillable: bool,
254 #[serde(default)]
255 pub filterable: bool,
256 #[serde(default)]
257 pub sortable: bool,
258 #[serde(default)]
259 pub groupable: bool,
260 pub aggregatable: Option<bool>,
261 pub searchable: Option<bool>,
262 #[serde(default)]
263 pub unique: bool,
264 pub permissionable: Option<bool>,
265
266 #[serde(rename = "externalId", default)]
268 pub external_id: bool,
269 #[serde(rename = "idLookup", default)]
270 pub id_lookup: bool,
271 #[serde(default)]
272 pub calculated: bool,
273 #[serde(rename = "calculatedFormula")]
274 pub calculated_formula: Option<String>,
275 #[serde(rename = "autoNumber", default)]
276 pub auto_number: bool,
277 #[serde(default)]
278 pub encrypted: bool,
279 #[serde(rename = "nameField")]
280 pub name_field: Option<bool>,
281 #[serde(rename = "namePointing")]
282 pub name_pointing: Option<bool>,
283 #[serde(rename = "caseSensitive")]
284 pub case_sensitive: Option<bool>,
285 #[serde(rename = "htmlFormatted")]
286 pub html_formatted: Option<bool>,
287 #[serde(rename = "highScaleNumber")]
288 pub high_scale_number: Option<bool>,
289 #[serde(rename = "displayLocationInDecimal")]
290 pub display_location_in_decimal: Option<bool>,
291 #[serde(rename = "queryByDistance")]
292 pub query_by_distance: Option<bool>,
293
294 #[serde(rename = "defaultValue")]
296 pub default_value: Option<serde_json::Value>,
297 #[serde(rename = "defaultValueFormula")]
298 pub default_value_formula: Option<String>,
299 #[serde(rename = "defaultedOnCreate")]
300 pub defaulted_on_create: Option<bool>,
301 #[serde(rename = "formulaTreatNullNumberAsZero")]
302 pub formula_treat_null_number_as_zero: Option<bool>,
303
304 #[serde(rename = "referenceTo", default)]
306 pub reference_to: Option<Vec<String>>,
307 #[serde(rename = "relationshipName")]
308 pub relationship_name: Option<String>,
309 #[serde(rename = "relationshipOrder")]
310 pub relationship_order: Option<i32>,
311 #[serde(rename = "referenceTargetField")]
312 pub reference_target_field: Option<String>,
313 #[serde(rename = "polymorphicForeignKey")]
314 pub polymorphic_foreign_key: Option<bool>,
315 #[serde(rename = "cascadeDelete")]
316 pub cascade_delete: Option<bool>,
317 #[serde(rename = "restrictedDelete")]
318 pub restricted_delete: Option<bool>,
319 #[serde(rename = "writeRequiresMasterRead")]
320 pub write_requires_master_read: Option<bool>,
321
322 #[serde(rename = "compoundFieldName")]
324 pub compound_field_name: Option<String>,
325 #[serde(rename = "extraTypeInfo")]
326 pub extra_type_info: Option<String>,
327
328 #[serde(rename = "picklistValues", default)]
330 pub picklist_values: Option<Vec<PicklistValue>>,
331 #[serde(rename = "dependentPicklist")]
332 pub dependent_picklist: Option<bool>,
333 #[serde(rename = "controllerName")]
334 pub controller_name: Option<String>,
335 #[serde(rename = "restrictedPicklist")]
336 pub restricted_picklist: Option<bool>,
337
338 #[serde(rename = "filteredLookupInfo")]
340 pub filtered_lookup_info: Option<FilteredLookupInfo>,
341 #[serde(rename = "searchPrefilterable")]
342 pub search_prefilterable: Option<bool>,
343
344 pub mask: Option<String>,
346 #[serde(rename = "maskType")]
347 pub mask_type: Option<String>,
348
349 #[serde(rename = "aiPredictionField")]
351 pub ai_prediction_field: Option<bool>,
352
353 #[serde(rename = "deprecatedAndHidden")]
355 pub deprecated_and_hidden: Option<bool>,
356 #[serde(rename = "inlineHelpText")]
357 pub inline_help_text: Option<String>,
358}
359
360#[derive(Debug, Clone, Deserialize, Serialize)]
362pub struct FilteredLookupInfo {
363 #[serde(rename = "controllingFields", default)]
364 pub controlling_fields: Vec<String>,
365 pub dependent: Option<bool>,
366 #[serde(rename = "optionalFilter")]
367 pub optional_filter: Option<bool>,
368}
369
370#[derive(Debug, Clone, Deserialize, Serialize)]
372pub struct PicklistValue {
373 pub value: String,
374 pub label: String,
375 pub active: bool,
376 #[serde(rename = "defaultValue")]
377 pub default_value: bool,
378 #[serde(rename = "validFor")]
379 pub valid_for: Option<String>,
380}
381
382#[cfg(test)]
383mod tests {
384 use super::*;
385
386 #[test]
387 fn test_describe_global_result_deser() {
388 let json = r#"{
389 "encoding": "UTF-8",
390 "maxBatchSize": 200,
391 "sobjects": [{
392 "name": "Account",
393 "label": "Account",
394 "labelPlural": "Accounts",
395 "keyPrefix": "001",
396 "custom": false,
397 "queryable": true,
398 "createable": true,
399 "updateable": true,
400 "deletable": true,
401 "searchable": true,
402 "retrieveable": true
403 }]
404 }"#;
405
406 let result: DescribeGlobalResult = serde_json::from_str(json).unwrap();
407 assert_eq!(result.encoding, "UTF-8");
408 assert_eq!(result.max_batch_size, 200);
409 assert_eq!(result.sobjects.len(), 1);
410 assert_eq!(result.sobjects[0].name, "Account");
411 }
412
413 #[test]
414 fn test_field_describe_deser() {
415 let json = r#"{
416 "name": "Name",
417 "label": "Account Name",
418 "type": "string",
419 "length": 255,
420 "createable": true,
421 "updateable": true,
422 "nillable": false,
423 "filterable": true,
424 "sortable": true,
425 "groupable": true,
426 "unique": false
427 }"#;
428
429 let field: FieldDescribe = serde_json::from_str(json).unwrap();
430 assert_eq!(field.name, "Name");
431 assert_eq!(field.field_type, "string");
432 assert_eq!(field.length, Some(255));
433 assert!(field.createable);
434 assert!(!field.nillable);
435 }
436
437 #[test]
438 fn test_picklist_value_deser() {
439 let json = r#"{
440 "value": "Hot",
441 "label": "Hot",
442 "active": true,
443 "defaultValue": false
444 }"#;
445
446 let pv: PicklistValue = serde_json::from_str(json).unwrap();
447 assert_eq!(pv.value, "Hot");
448 assert_eq!(pv.label, "Hot");
449 assert!(pv.active);
450 assert!(!pv.default_value);
451 }
452}