Skip to main content

mailchimp/types/
list.rs

1use super::contact::ContactType;
2use super::empty::EmptyType;
3use super::link::LinkType;
4
5use super::list_abuse_report::{
6    CollectionListAbuseReport, ListAbuseReportBuilder, ListAbuseReportType,
7};
8use super::list_activity::{CollectionListActivity, ListActivityBuilder};
9use super::list_batch_members::{ListBatchParam, ListBatchResponse};
10use super::list_clients::{CollectionListClients, ListClientsBuilder};
11use super::list_growth_history::{
12    CollectionListGrowthHistory, ListGrowthHistoryBuilder, ListGrowthHistoryFilter,
13    ListGrowthHistoryType,
14};
15use super::list_interest_categories::{
16    CollectionListInterestCategories, InterestCategoryParam, ListInterestCategory,
17    ListInterestCategoryBuilder, ListInterestCategoryFilter,
18};
19use super::list_locations::{CollectionListLocations, ListLocationsBuilder};
20use super::list_members::{
21    CollectionListMembers, ListMember, ListMemberParams, ListMembersBuilder, ListMembersFilter,
22};
23use super::list_merge_fields::{
24    CollectionListMergeField, ListMergeField, ListMergeFieldBuilder, ListMergeFieldFilter,
25    ListMergeFieldParam,
26};
27use super::list_segments::{
28    CollectionListSegment, ListSegment, ListSegmentBuilder, ListSegmentFilter,
29};
30use super::list_signup_forms::{CollectionListSignupForm, ListSignupForm, ListSignupFormBuilder};
31use super::list_webhooks::{
32    CollectionListWebhooks, ListWebhooks, ListWebhooksBuilder, ListWebhooksParam,
33};
34use crate::api::{MailchimpApi, MailchimpApiUpdate};
35use crate::internal::error_type::MailchimpErrorType;
36use crate::internal::request::MailchimpResult;
37use crate::iter::MailchimpCollection;
38use crate::iter::{MalchimpIter, ResourceFilter, SimpleFilter};
39use log::error;
40use serde::{Deserialize, Serialize};
41use std::collections::HashMap;
42use std::rc::Rc;
43
44///
45/// Campaign Defaults Type
46///
47#[derive(Serialize, Deserialize, Debug, Clone)]
48pub struct CampaignDefaultsType {
49    /// The default from name for campaigns sent to this list.
50    #[serde(default, skip_serializing_if = "Option::is_none")]
51    pub from_name: Option<String>,
52    /// The default from email for campaigns sent to this list.
53    #[serde(default, skip_serializing_if = "Option::is_none")]
54    pub from_email: Option<String>,
55    /// The default subject line for campaigns sent to this list.
56    #[serde(default, skip_serializing_if = "Option::is_none")]
57    pub subject: Option<String>,
58    /// The default language for this lists’s forms.
59    #[serde(default, skip_serializing_if = "Option::is_none")]
60    pub language: Option<String>,
61}
62
63impl Default for CampaignDefaultsType {
64    fn default() -> Self {
65        CampaignDefaultsType {
66            from_name: None,
67            from_email: None,
68            subject: None,
69            language: None,
70        }
71    }
72}
73
74///
75/// Statistics
76///
77#[derive(Serialize, Deserialize, Debug, Clone)]
78pub struct StatisticsType {
79    /// The number of active members in the list.
80    #[serde(default, skip_serializing_if = "Option::is_none")]
81    pub member_count: Option<u64>,
82    /// The number of members who have unsubscribed from the list.
83    #[serde(default, skip_serializing_if = "Option::is_none")]
84    pub unsubscribe_count: Option<u64>,
85    /// The number of members cleaned from the list.
86    #[serde(default, skip_serializing_if = "Option::is_none")]
87    pub cleaned_count: Option<u64>,
88    /// The number of active members in the list since the last campaign was sent.
89    #[serde(default, skip_serializing_if = "Option::is_none")]
90    pub member_count_since_send: Option<u64>,
91    /// The number of members who have unsubscribed since the last campaign was sent.
92    #[serde(default, skip_serializing_if = "Option::is_none")]
93    pub unsubscribe_count_since_send: Option<u64>,
94    /// The number of members cleaned from the list since the last campaign was sent.
95    #[serde(default, skip_serializing_if = "Option::is_none")]
96    pub cleaned_count_since_send: Option<u64>,
97    /// The number of campaigns in any status that use this list.
98    #[serde(default, skip_serializing_if = "Option::is_none")]
99    pub campaign_count: Option<u64>,
100    /// The date and time the last campaign was sent to this list in ISO 8601 format.
101    ///  This is updated when a campaign is sent to 10 or more recipients.
102    #[serde(default, skip_serializing_if = "Option::is_none")]
103    pub campaign_last_sent: Option<String>,
104    /// The number of merge vars for this list (not EMAIL, which is required).
105    #[serde(default, skip_serializing_if = "Option::is_none")]
106    pub merge_field_count: Option<u64>,
107    /// The average number of subscriptions per month for the list (not returned
108    /// if we haven’t calculated it yet).
109    #[serde(default, skip_serializing_if = "Option::is_none")]
110    pub avg_sub_rate: Option<f32>,
111    /// The average number of unsubscriptions per month for the list (not returned
112    /// if we haven’t calculated it yet).
113    #[serde(default, skip_serializing_if = "Option::is_none")]
114    pub avg_unsub_rate: Option<f32>,
115    /// The target number of subscriptions per month for the list to keep
116    /// it growing (not returned if we haven’t calculated it yet).
117    #[serde(default, skip_serializing_if = "Option::is_none")]
118    pub target_sub_rate: Option<f32>,
119    /// The average open rate (a percentage represented as a number between
120    /// 0 and 100) per campaign for the list (not returned if we haven’t calculated it yet).
121    #[serde(default, skip_serializing_if = "Option::is_none")]
122    pub open_rate: Option<f32>,
123    /// The average click rate (a percentage represented as a number between 0 and 100)
124    /// per campaign for the list (not returned if we haven’t calculated it yet).
125    #[serde(default, skip_serializing_if = "Option::is_none")]
126    pub click_rate: Option<f32>,
127    /// The date and time of the last time someone subscribed to this list in ISO 8601 format.
128    #[serde(default, skip_serializing_if = "Option::is_none")]
129    pub last_sub_date: Option<String>,
130    /// The date and time of the last time someone unsubscribed from this list in ISO 8601 format.
131    #[serde(default, skip_serializing_if = "Option::is_none")]
132    pub last_unsub_date: Option<String>,
133}
134
135impl Default for StatisticsType {
136    fn default() -> Self {
137        StatisticsType {
138            member_count: None,
139            unsubscribe_count: None,
140            cleaned_count: None,
141            member_count_since_send: None,
142            unsubscribe_count_since_send: None,
143            cleaned_count_since_send: None,
144            campaign_count: None,
145            campaign_last_sent: None,
146            merge_field_count: None,
147            avg_sub_rate: None,
148            avg_unsub_rate: None,
149            target_sub_rate: None,
150            open_rate: None,
151            click_rate: None,
152            last_sub_date: None,
153            last_unsub_date: None,
154        }
155    }
156}
157
158///
159/// List Type
160///
161/// Endpoint
162///      GET /lists/{list_id}
163///
164#[derive(Serialize, Deserialize, Debug, Clone)]
165pub struct ListType {
166    /// A string that uniquely identifies this list.
167    #[serde(default, skip_serializing_if = "Option::is_none")]
168    pub id: Option<String>,
169    /// The ID used in the Mailchimp web application. View this list in
170    /// your Mailchimp account at https://{dc}.admin.mailchimp.com/lists/members/?id={web_id}.
171    #[serde(default, skip_serializing_if = "Option::is_none")]
172    pub web_id: Option<u64>,
173    /// The name of the list.
174    #[serde(default, skip_serializing_if = "Option::is_none")]
175    pub name: Option<String>,
176    /// Contact information displayed in campaign footers to comply with international spam laws.
177    #[serde(default, skip_serializing_if = "Option::is_none")]
178    pub contact: Option<ContactType>,
179    /// The permission reminder for the list.
180    #[serde(default, skip_serializing_if = "Option::is_none")]
181    pub permission_reminder: Option<String>,
182    /// Whether campaigns for this list use the Archive Bar in archives by default.
183    #[serde(default, skip_serializing_if = "Option::is_none")]
184    pub use_archive_bar: Option<bool>,
185    /// Default values for campaigns created for this list.
186    #[serde(default, skip_serializing_if = "Option::is_none")]
187    pub campaign_defaults: Option<CampaignDefaultsType>,
188    /// The email address to send subscribe notifications to.
189    #[serde(default, skip_serializing_if = "Option::is_none")]
190    pub notify_on_subscribe: Option<String>,
191    /// The email address to send unsubscribe notifications to.
192    #[serde(default, skip_serializing_if = "Option::is_none")]
193    pub notify_on_unsubscribe: Option<String>,
194    /// The date and time that this list was created in ISO 8601 format.
195    #[serde(default, skip_serializing_if = "Option::is_none")]
196    pub date_created: Option<String>,
197    /// An auto-generated activity score for the list (0-5).
198    #[serde(default, skip_serializing_if = "Option::is_none")]
199    pub list_rating: Option<u64>,
200    /// Whether the list supports multiple formats for emails. When set to true,
201    /// subscribers can choose whether they want to receive HTML or plain-text
202    /// emails. When set to false, subscribers will receive HTML emails,
203    ///  with a plain-text alternative backup.
204    #[serde(default, skip_serializing_if = "Option::is_none")]
205    pub email_type_option: Option<bool>,
206    /// Our EepURL shortened version of this list’s subscribe form.
207    #[serde(default, skip_serializing_if = "Option::is_none")]
208    pub subscribe_url_short: Option<String>,
209    /// The full version of this list’s subscribe form (host will vary).
210    #[serde(default, skip_serializing_if = "Option::is_none")]
211    pub subscribe_url_long: Option<String>,
212    /// The list’s Email Beamer address.
213    #[serde(default, skip_serializing_if = "Option::is_none")]
214    pub beamer_address: Option<String>,
215    /// Whether this list is public or private.
216    #[serde(default, skip_serializing_if = "Option::is_none")]
217    pub visibility: Option<String>,
218    /// Whether or not to require the subscriber to confirm subscription via email.
219    #[serde(default, skip_serializing_if = "Option::is_none")]
220    pub double_optin: Option<bool>,
221    /// Whether or not this list has a welcome automation connected. Welcome
222    /// Automations: welcomeSeries, singleWelcome, emailFollowup.
223    #[serde(default, skip_serializing_if = "Option::is_none")]
224    pub has_welcome: Option<bool>,
225    /// Whether or not the list has marketing permissions (eg. GDPR) enabled.
226    #[serde(default, skip_serializing_if = "Option::is_none")]
227    pub marketing_permissions: Option<bool>,
228    /// Any list-specific modules installed for this list.
229    #[serde(default, skip_serializing_if = "Option::is_none")]
230    pub modules: Option<Vec<String>>,
231    /// Stats for the list. Many of these are cached for at least five minutes.
232    #[serde(default, skip_serializing_if = "Option::is_none")]
233    pub stats: Option<StatisticsType>,
234    /// Desc: A list of link types and descriptions for the API schema documents.
235    #[serde(default, skip_serializing_if = "Option::is_none")]
236    pub _links: Option<Vec<LinkType>>,
237
238    #[serde(skip)]
239    _api: Rc<MailchimpApi>,
240}
241
242///
243/// MailchimpApiUpdate Impl
244///
245impl MailchimpApiUpdate for ListType {
246    /**
247     * Update API
248     */
249    fn set_api(&mut self, n_api: Rc<MailchimpApi>) {
250        self._api = n_api
251    }
252}
253
254///
255/// List Type
256///
257/// Endpoint
258///      GET /lists
259///
260#[derive(Serialize, Deserialize, Debug, Clone)]
261pub struct ListsType {
262    /// An array of objects, each representing an email in an Automation workflow.
263    #[serde(default)]
264    pub lists: Vec<ListType>,
265    /// Desc: The total number of items matching the query regardless of pagination.
266    #[serde(default)]
267    pub total_items: u64,
268    /// Desc: A list of link types and descriptions for the API schema documents.
269    #[serde(default)]
270    pub _links: Vec<LinkType>,
271}
272
273impl MailchimpCollection<ListType> for ListsType {
274    /// Total Items
275    fn get_total_items(&self) -> u64 {
276        self.total_items
277    }
278    /// Data
279    fn get_values(&self) -> Vec<ListType> {
280        self.lists.clone()
281    }
282}
283
284impl Default for ListsType {
285    fn default() -> Self {
286        ListsType {
287            lists: Vec::new(),
288            total_items: 0,
289            _links: Vec::new(),
290        }
291    }
292}
293
294impl ListType {
295    ///
296    /// Batch subscribe or unsubscribe list members.
297    ///
298    pub fn batch_list_members(&self, param: ListBatchParam) -> MailchimpResult<ListBatchResponse> {
299        // POST /lists/{list_id}
300        let endpoint = self.get_base_endpoint();
301        self._api
302            .post::<ListBatchResponse, ListBatchParam>(&endpoint, param)
303    }
304
305    ///
306    /// Get up to the previous 180 days of daily detailed aggregated activity
307    /// stats for a list, not including Automation activity.
308    ///
309    /// Arguments:
310    ///     fields: A comma-separated list of fields to return. Reference
311    ///         parameters of sub-objects with dot notation.
312    ///     exclude_fields: A comma-separated list of fields to exclude. Reference
313    ///         parameters of sub-objects with dot notation.
314    ///
315    pub fn get_activity(
316        &self,
317        fields: Option<String>,
318        exclude_fields: Option<String>,
319    ) -> MalchimpIter<ListActivityBuilder> {
320        let endpoint = self.get_base_endpoint() + "/activity";
321        let mut filter_params = SimpleFilter::default();
322
323        if let Some(f) = fields {
324            filter_params.fields = Some(f);
325        }
326
327        if let Some(ex) = exclude_fields {
328            filter_params.exclude_fields = Some(ex);
329        }
330
331        match self
332            ._api
333            .get::<CollectionListActivity>(&endpoint, filter_params.build_payload())
334        {
335            Ok(collection) => MalchimpIter {
336                builder: ListActivityBuilder {},
337                data: collection.activity,
338                cur_filters: filter_params.clone(),
339                cur_it: 0,
340                total_items: collection.total_items,
341                api: self._api.clone(),
342                endpoint: endpoint.clone(),
343            },
344            Err(e) => {
345                error!( target: "mailchimp",  "Get Activities: Response Error details: {:?}", e);
346                MalchimpIter {
347                    builder: ListActivityBuilder {},
348                    data: Vec::new(),
349                    cur_filters: filter_params.clone(),
350                    cur_it: 0,
351                    total_items: 0,
352                    api: self._api.clone(),
353                    endpoint: endpoint.clone(),
354                }
355            }
356        }
357    }
358
359    ///
360    /// Get a list of all merge fields (formerly merge vars) for a list.
361    ///
362    pub fn get_merge_fields(
363        &self,
364        filter: Option<ListMergeFieldFilter>,
365    ) -> MalchimpIter<ListMergeFieldBuilder> {
366        // GET /lists/{list_id}/merge-fields
367        let endpoint = self.get_base_endpoint() + "/merge-fields";
368        let mut filter_params = ListMergeFieldFilter::default();
369
370        if let Some(f) = filter {
371            filter_params = f;
372        }
373
374        match self
375            ._api
376            .get::<CollectionListMergeField>(&endpoint, filter_params.build_payload())
377        {
378            Ok(collection) => MalchimpIter {
379                builder: ListMergeFieldBuilder {
380                    endpoint: endpoint.clone(),
381                },
382                data: collection.merge_fields,
383                cur_filters: filter_params.clone(),
384                cur_it: 0,
385                total_items: collection.total_items,
386                api: self._api.clone(),
387                endpoint: endpoint.clone(),
388            },
389            Err(e) => {
390                error!( target: "mailchimp",  "Get Activities: Response Error details: {:?}", e);
391                MalchimpIter {
392                    builder: ListMergeFieldBuilder {
393                        endpoint: endpoint.clone(),
394                    },
395                    data: Vec::new(),
396                    cur_filters: filter_params.clone(),
397                    cur_it: 0,
398                    total_items: 0,
399                    api: self._api.clone(),
400                    endpoint: endpoint.clone(),
401                }
402            }
403        }
404    }
405
406    ///
407    /// Get information about a specific merge field in a list.
408    ///
409    pub fn get_specific_merge_field<'a>(
410        &self,
411        merge_id: &'a str,
412    ) -> MailchimpResult<ListMergeField> {
413        // GET /lists/{list_id}/merge-fields/{merge_id}
414        let endpoint = self.get_base_endpoint() + "/merge-fields/";
415
416        match self
417            ._api
418            .get::<ListMergeField>(&(endpoint.clone() + merge_id), HashMap::new())
419        {
420            Ok(data) => {
421                let mut n_data = data.clone();
422                n_data.set_api(self._api.clone());
423                n_data.set_endpoint(&endpoint.clone());
424                Ok(data)
425            }
426            Err(e) => Err(e),
427        }
428    }
429
430    ///
431    /// Add a new merge field
432    ///
433    pub fn create_merge_field(
434        &self,
435        param: ListMergeFieldParam,
436    ) -> MailchimpResult<ListMergeField> {
437        // POST /lists/{list_id}/merge-fields
438        let endpoint = self.get_base_endpoint() + "/merge-fields";
439        match self
440            ._api
441            .post::<ListMergeField, ListMergeFieldParam>(&endpoint, param)
442        {
443            Ok(data) => {
444                let mut n_data = data.clone();
445                n_data.set_api(self._api.clone());
446                n_data.set_endpoint(&endpoint);
447                Ok(n_data)
448            }
449            Err(e) => Err(e),
450        }
451    }
452    ///
453    /// Get information about all webhooks for a specific list
454    ///
455    pub fn get_webhooks(&self, filter: Option<SimpleFilter>) -> MalchimpIter<ListWebhooksBuilder> {
456        // GET /lists/{list_id}/webhooks
457        let endpoint = self.get_base_endpoint() + "/webhooks";
458        let mut filter_params = SimpleFilter::default();
459        println!("{}", &endpoint);
460
461        if let Some(f) = filter {
462            filter_params = f;
463        }
464
465        match self
466            ._api
467            .get::<CollectionListWebhooks>(&endpoint, filter_params.build_payload())
468        {
469            Ok(collection) => MalchimpIter {
470                builder: ListWebhooksBuilder {
471                    endpoint: endpoint.clone(),
472                },
473                data: collection.webhooks,
474                cur_filters: filter_params.clone(),
475                cur_it: 0,
476                total_items: collection.total_items,
477                api: self._api.clone(),
478                endpoint: endpoint.clone(),
479            },
480            Err(e) => {
481                error!( target: "mailchimp",  "Get Activities: Response Error details: {:?}", e);
482                MalchimpIter {
483                    builder: ListWebhooksBuilder {
484                        endpoint: endpoint.clone(),
485                    },
486                    data: Vec::new(),
487                    cur_filters: filter_params.clone(),
488                    cur_it: 0,
489                    total_items: 0,
490                    api: self._api.clone(),
491                    endpoint: endpoint.clone(),
492                }
493            }
494        }
495    }
496
497    ///
498    /// Get information about a specific webhook.
499    ///
500    pub fn get_specific_webhook<'a>(&self, webkook_id: &'a str) -> MailchimpResult<ListWebhooks> {
501        // GET /lists/{list_id}/webhooks/{webhook_id}
502        let endpoint = self.get_base_endpoint() + "/webhooks/";
503
504        match self
505            ._api
506            .get::<ListWebhooks>(&(endpoint.clone() + webkook_id), HashMap::new())
507        {
508            Ok(data) => {
509                let mut n_data = data.clone();
510                n_data.set_api(self._api.clone());
511                n_data.set_endpoint(&endpoint.clone());
512                Ok(data)
513            }
514            Err(e) => Err(e),
515        }
516    }
517
518    ///
519    /// Create a new webhook for a specific list.
520    ///
521    pub fn create_webhook(&self, param: ListWebhooksParam) -> MailchimpResult<ListWebhooks> {
522        // POST /lists/{list_id}/webhooks
523        let endpoint = self.get_base_endpoint() + "/webhooks";
524        match self
525            ._api
526            .post::<ListWebhooks, ListWebhooksParam>(&endpoint, param)
527        {
528            Ok(data) => {
529                let mut n_data = data.clone();
530                n_data.set_api(self._api.clone());
531                n_data.set_endpoint(&endpoint);
532                Ok(n_data)
533            }
534            Err(e) => Err(e),
535        }
536    }
537    ///
538    /// Get a list of the top email clients based on user-agent strings.
539    ///
540    /// Arguments:
541    ///     fields: A comma-separated list of fields to return. Reference
542    ///         parameters of sub-objects with dot notation.
543    ///     exclude_fields: A comma-separated list of fields to exclude. Reference
544    ///         parameters of sub-objects with dot notation.
545    ///
546    pub fn get_clients(
547        &self,
548        fields: Option<String>,
549        exclude_fields: Option<String>,
550    ) -> MalchimpIter<ListClientsBuilder> {
551        // GET /lists/{list_id}/clients
552        let endpoint = self.get_base_endpoint() + "/clients";
553        let mut filter_params = SimpleFilter::default();
554
555        if let Some(f) = fields {
556            filter_params.fields = Some(f);
557        }
558
559        if let Some(ex) = exclude_fields {
560            filter_params.exclude_fields = Some(ex);
561        }
562
563        match self
564            ._api
565            .get::<CollectionListClients>(&endpoint, filter_params.build_payload())
566        {
567            Ok(collection) => MalchimpIter {
568                builder: ListClientsBuilder {},
569                data: collection.clients,
570                cur_filters: filter_params.clone(),
571                cur_it: 0,
572                total_items: collection.total_items,
573                api: self._api.clone(),
574                endpoint: endpoint.clone(),
575            },
576            Err(e) => {
577                error!( target: "mailchimp",  "Get Clients: Response Error details: {:?}", e);
578                MalchimpIter {
579                    builder: ListClientsBuilder {},
580                    data: Vec::new(),
581                    cur_filters: filter_params.clone(),
582                    cur_it: 0,
583                    total_items: 0,
584                    api: self._api.clone(),
585                    endpoint: endpoint.clone(),
586                }
587            }
588        }
589    }
590
591    ///
592    /// Get the locations (countries) that the list’s subscribers have been tagged to
593    /// based on geocoding their IP address.
594    ///
595    /// Arguments:
596    ///     fields: A comma-separated list of fields to return. Reference
597    ///         parameters of sub-objects with dot notation.
598    ///     exclude_fields: A comma-separated list of fields to exclude. Reference
599    ///         parameters of sub-objects with dot notation.
600    ///
601    pub fn get_locations(
602        &self,
603        fields: Option<String>,
604        exclude_fields: Option<String>,
605    ) -> MalchimpIter<ListLocationsBuilder> {
606        // GET /lists/{list_id}/locations
607        let endpoint = self.get_base_endpoint() + "/locations";
608        let mut filter_params = SimpleFilter::default();
609
610        if let Some(f) = fields {
611            filter_params.fields = Some(f);
612        }
613
614        if let Some(ex) = exclude_fields {
615            filter_params.exclude_fields = Some(ex);
616        }
617
618        match self
619            ._api
620            .get::<CollectionListLocations>(&endpoint, filter_params.build_payload())
621        {
622            Ok(collection) => MalchimpIter {
623                builder: ListLocationsBuilder {},
624                data: collection.locations,
625                cur_filters: filter_params.clone(),
626                cur_it: 0,
627                total_items: collection.total_items,
628                api: self._api.clone(),
629                endpoint: endpoint.clone(),
630            },
631            Err(e) => {
632                error!( target: "mailchimp",  "Get Locations: Response Error details: {:?}", e);
633                MalchimpIter {
634                    builder: ListLocationsBuilder {},
635                    data: Vec::new(),
636                    cur_filters: filter_params.clone(),
637                    cur_it: 0,
638                    total_items: 0,
639                    api: self._api.clone(),
640                    endpoint: endpoint.clone(),
641                }
642            }
643        }
644    }
645
646    ///
647    /// Get all abuse reports for a specific list.
648    ///
649    /// Arguments:
650    ///     fields: A comma-separated list of fields to return. Reference
651    ///         parameters of sub-objects with dot notation.
652    ///     exclude_fields: A comma-separated list of fields to exclude. Reference
653    ///         parameters of sub-objects with dot notation.
654    ///     offset: The number of records from a collection to skip.
655    ///         Iterating over large collections with this parameter can be slow.
656    ///         Default value is 0.
657    ///
658    pub fn get_abuse_reports(
659        &self,
660        fields: Option<String>,
661        exclude_fields: Option<String>,
662        offset: Option<u64>,
663    ) -> MalchimpIter<ListAbuseReportBuilder> {
664        // GET /lists/{list_id}/abuse-reports
665        let endpoint = self.get_base_endpoint() + "/abuse-reports";
666        let mut filter_params = SimpleFilter::default();
667
668        if let Some(f) = fields {
669            filter_params.fields = Some(f);
670        }
671
672        if let Some(ex) = exclude_fields {
673            filter_params.exclude_fields = Some(ex);
674        }
675        if let Some(ofs) = offset {
676            filter_params.offset = Some(ofs);
677        }
678
679        match self
680            ._api
681            .get::<CollectionListAbuseReport>(&endpoint, filter_params.build_payload())
682        {
683            Ok(collection) => MalchimpIter {
684                builder: ListAbuseReportBuilder {},
685                data: collection.abuse_reports,
686                cur_filters: filter_params.clone(),
687                cur_it: 0,
688                total_items: collection.total_items,
689                api: self._api.clone(),
690                endpoint: endpoint.clone(),
691            },
692            Err(e) => {
693                error!( target: "mailchimp",  "Get Abuse Reports: Response Error details: {:?}", e);
694                MalchimpIter {
695                    builder: ListAbuseReportBuilder {},
696                    data: Vec::new(),
697                    cur_filters: filter_params.clone(),
698                    cur_it: 0,
699                    total_items: 0,
700                    api: self._api.clone(),
701                    endpoint: endpoint.clone(),
702                }
703            }
704        }
705    }
706
707    ///
708    /// Get details about a specific abuse report.
709    ///
710    /// Arguments:
711    ///     report_id: Abuse Report Id
712    ///
713    pub fn get_specific_abuse_report<'a>(
714        &self,
715        report_id: &'a str,
716    ) -> MailchimpResult<ListAbuseReportType> {
717        // GET /lists/{list_id}/abuse-reports/{report_id}
718        let mut endpoint = self.get_base_endpoint() + "/abuse-reports/";
719        endpoint.push_str(report_id);
720
721        self._api
722            .get::<ListAbuseReportType>(&endpoint, HashMap::new())
723    }
724
725    ///
726    /// Get a month-by-month summary of a specific list’s growth activity.
727    ///
728    /// Arguments:
729    ///     fields: A comma-separated list of fields to return. Reference
730    ///         parameters of sub-objects with dot notation.
731    ///     exclude_fields: A comma-separated list of fields to exclude. Reference
732    ///         parameters of sub-objects with dot notation.
733    ///     sort_dir: Determines the order direction for sorted results.
734    ///
735    pub fn get_growth_history(
736        &self,
737        fields: Option<String>,
738        exclude_fields: Option<String>,
739        sort_dir: Option<String>,
740    ) -> MalchimpIter<ListGrowthHistoryBuilder> {
741        // GET /lists/{list_id}/growth-history
742        let endpoint = self.get_base_endpoint() + "/growth-history";
743        let mut filter_params = ListGrowthHistoryFilter::default();
744
745        if let Some(f) = fields {
746            filter_params.fields = Some(f);
747        }
748
749        if let Some(ex) = exclude_fields {
750            filter_params.exclude_fields = Some(ex);
751        }
752        if let Some(ofs) = sort_dir {
753            filter_params.sort_dir = Some(ofs);
754        }
755
756        match self
757            ._api
758            .get::<CollectionListGrowthHistory>(&endpoint, filter_params.build_payload())
759        {
760            Ok(collection) => MalchimpIter {
761                builder: ListGrowthHistoryBuilder {},
762                data: collection.history,
763                cur_filters: filter_params.clone(),
764                cur_it: 0,
765                total_items: collection.total_items,
766                api: self._api.clone(),
767                endpoint: endpoint.clone(),
768            },
769            Err(e) => {
770                error!( target: "mailchimp",  "Get Grow History: Response Error details: {:?}", e);
771                MalchimpIter {
772                    builder: ListGrowthHistoryBuilder {},
773                    data: Vec::new(),
774                    cur_filters: filter_params.clone(),
775                    cur_it: 0,
776                    total_items: 0,
777                    api: self._api.clone(),
778                    endpoint: endpoint.clone(),
779                }
780            }
781        }
782    }
783
784    ///
785    /// Get a summary of a specific list’s growth activity for a specific month and year.
786    ///
787    /// Arguments:
788    ///     month: A specific month of list growth history.
789    ///
790    pub fn get_growth_history_info<'a>(
791        &self,
792        month: &'a str,
793    ) -> MailchimpResult<ListGrowthHistoryType> {
794        // GET /lists/{list_id}/growth-history/{month}
795        let mut endpoint = self.get_base_endpoint() + "/growth-history/";
796        endpoint.push_str(month);
797
798        self._api
799            .get::<ListGrowthHistoryType>(&endpoint, HashMap::new())
800    }
801
802    ///
803    /// Get information about members in a list
804    ///
805    /// Arguments:
806    ///     filter: Params to filter the response
807    ///
808    pub fn get_members(
809        &self,
810        filter: Option<ListMembersFilter>,
811    ) -> MalchimpIter<ListMembersBuilder> {
812        // GET /lists/{list_id}/members
813        let endpoint = self.get_base_endpoint() + "/members";
814        let filter_params = if let Some(f) = filter {
815            f
816        } else {
817            ListMembersFilter::default()
818        };
819
820        match self
821            ._api
822            .get::<CollectionListMembers>(&endpoint, filter_params.build_payload())
823        {
824            Ok(collection) => MalchimpIter {
825                builder: ListMembersBuilder {
826                    endpoint: endpoint.clone(),
827                },
828                data: collection.members,
829                cur_filters: filter_params.clone(),
830                cur_it: 0,
831                total_items: collection.total_items,
832                api: self._api.clone(),
833                endpoint: endpoint.clone(),
834            },
835            Err(e) => {
836                error!( target: "mailchimp",  "Get List Members: Response Error details: {:?}", e);
837                MalchimpIter {
838                    builder: ListMembersBuilder {
839                        endpoint: endpoint.clone(),
840                    },
841                    data: Vec::new(),
842                    cur_filters: filter_params.clone(),
843                    cur_it: 0,
844                    total_items: 0,
845                    api: self._api.clone(),
846                    endpoint: endpoint.clone(),
847                }
848            }
849        }
850    }
851
852    ///
853    /// Get information about a specific list member, including a currently subscribed,
854    /// unsubscribed, or bounced member.
855    ///
856    /// Arguments:
857    ///     subscriber_hash: The MD5 hash of the lowercase version of the list member’s email address.
858    ///
859    pub fn get_member_info<'a>(&self, subscriber_hash: &'a str) -> MailchimpResult<ListMember> {
860        // GET /lists/{list_id}/members/{subscriber_hash}
861        let mut endpoint = self.get_base_endpoint() + "/members/";
862        endpoint.push_str(subscriber_hash);
863
864        self._api.get::<ListMember>(&endpoint, HashMap::new())
865    }
866
867    ///
868    /// Add a new member to the list.
869    ///
870    /// Arguments:
871    ///     param: New member fields
872    ///
873    pub fn add_new_member(&self, param: ListMemberParams) -> MailchimpResult<ListMember> {
874        // POST /lists/{list_id}/members
875        let endpoint = self.get_base_endpoint() + "/members";
876        self._api
877            .post::<ListMember, ListMemberParams>(&endpoint, param)
878    }
879
880    ///
881    /// Add or update a list member
882    ///
883    /// Arguments:
884    ///     subscriber_hash: The MD5 hash of the lowercase version of the list member’s email address.
885    ///     param: Member fields to update o create
886    ///
887    pub fn add_update_member<'a>(
888        &self,
889        subscriber_hash: &'a str,
890        param: ListMemberParams,
891    ) -> MailchimpResult<ListMember> {
892        // PUT /lists/{list_id}/members/{subscriber_hash}
893        let mut endpoint = self.get_base_endpoint() + "/members/";
894        endpoint.push_str(subscriber_hash);
895
896        self._api
897            .put::<ListMember, ListMemberParams>(&endpoint, param)
898    }
899
900    ///
901    /// Get information about a list’s interest categories.
902    ///
903    /// Arguments:
904    ///     filters
905    ///
906    pub fn get_interest_categories(
907        &self,
908        filters: Option<ListInterestCategoryFilter>,
909    ) -> MalchimpIter<ListInterestCategoryBuilder> {
910        // GET /lists/{list_id}/interest-categories
911        let mut endpoint = self.get_base_endpoint();
912        endpoint.push_str("/interest-categories");
913
914        let filter_params = if let Some(f) = filters {
915            f
916        } else {
917            ListInterestCategoryFilter::default()
918        };
919
920        match self
921            ._api
922            .get::<CollectionListInterestCategories>(&endpoint, filter_params.build_payload())
923        {
924            Ok(collection) => MalchimpIter {
925                builder: ListInterestCategoryBuilder {
926                    endpoint: endpoint.clone(),
927                },
928                data: collection.categories,
929                cur_filters: filter_params.clone(),
930                cur_it: 0,
931                total_items: collection.total_items,
932                api: self._api.clone(),
933                endpoint: endpoint.clone(),
934            },
935            Err(e) => {
936                error!( target: "mailchimp",  "Get List Members: Response Error details: {:?}", e);
937                MalchimpIter {
938                    builder: ListInterestCategoryBuilder {
939                        endpoint: endpoint.clone(),
940                    },
941                    data: Vec::new(),
942                    cur_filters: filter_params.clone(),
943                    cur_it: 0,
944                    total_items: 0,
945                    api: self._api.clone(),
946                    endpoint: endpoint.clone(),
947                }
948            }
949        }
950    }
951
952    ///
953    /// Get information about a specific interest category
954    ///
955    /// Argument:
956    ///     interest_category_id: A unique id for the interest category.
957    ///
958    pub fn get_specific_note<'a>(
959        &self,
960        interest_category_id: &'a str,
961    ) -> MailchimpResult<ListInterestCategory> {
962        // GET /lists/{list_id}/interest-categories/{interest_category_id}
963        let mut endpoint = self.get_base_endpoint();
964        endpoint.push_str("/interest-categories/");
965        endpoint.push_str(interest_category_id);
966
967        self._api
968            .get::<ListInterestCategory>(&endpoint, HashMap::new())
969    }
970
971    ///
972    /// Create a new interest category
973    ///
974    /// Argument:
975    ///     param: Content for Interest Category
976    ///
977    pub fn create_interest_category<'a>(
978        &self,
979        param: InterestCategoryParam,
980    ) -> MailchimpResult<ListInterestCategory> {
981        // POST /lists/{list_id}/interest-categories
982        let mut endpoint = self.get_base_endpoint();
983        endpoint.push_str("/interest-categories");
984
985        self._api
986            .post::<ListInterestCategory, InterestCategoryParam>(&endpoint, param)
987    }
988    ///
989    /// Customize the signup form settings for a specific list
990    ///
991    /// Argument:
992    ///     form: Signup Form content
993    ///
994    pub fn create_signup_form<'a>(&self, form: ListSignupForm) -> MailchimpResult<ListSignupForm> {
995        // POST /lists/{list_id}/signup-forms
996        let mut endpoint = self.get_base_endpoint();
997        endpoint.push_str("/signup-forms");
998        self._api
999            .post::<ListSignupForm, ListSignupForm>(&endpoint, form)
1000    }
1001
1002    ///
1003    /// Get signup forms for a specific list
1004    ///
1005    /// Arguments:
1006    ///     filters
1007    ///
1008    pub fn get_signup_forms(
1009        &self,
1010        filters: Option<SimpleFilter>,
1011    ) -> MalchimpIter<ListSignupFormBuilder> {
1012        // GET /lists/{list_id}/signup-forms
1013        let mut endpoint = self.get_base_endpoint();
1014        endpoint.push_str("/signup-forms");
1015
1016        let filter_params = if let Some(f) = filters {
1017            f
1018        } else {
1019            SimpleFilter::default()
1020        };
1021
1022        match self
1023            ._api
1024            .get::<CollectionListSignupForm>(&endpoint, filter_params.build_payload())
1025        {
1026            Ok(collection) => MalchimpIter {
1027                builder: ListSignupFormBuilder {},
1028                data: collection.signup_forms,
1029                cur_filters: filter_params.clone(),
1030                cur_it: 0,
1031                total_items: collection.total_items,
1032                api: self._api.clone(),
1033                endpoint: endpoint.clone(),
1034            },
1035            Err(e) => {
1036                error!( target: "mailchimp",  "Get List Members: Response Error details: {:?}", e);
1037                MalchimpIter {
1038                    builder: ListSignupFormBuilder {},
1039                    data: Vec::new(),
1040                    cur_filters: filter_params.clone(),
1041                    cur_it: 0,
1042                    total_items: 0,
1043                    api: self._api.clone(),
1044                    endpoint: endpoint.clone(),
1045                }
1046            }
1047        }
1048    }
1049
1050    ///
1051    /// Get information about all available segments for a specific list.
1052    ///
1053    pub fn get_segments(
1054        &self,
1055        filters: Option<ListSegmentFilter>,
1056    ) -> MalchimpIter<ListSegmentBuilder> {
1057        // GET /lists/{list_id}/segments
1058        let mut endpoint = self.get_base_endpoint();
1059        endpoint.push_str("/segments");
1060
1061        let filter_params = if let Some(f) = filters {
1062            f
1063        } else {
1064            ListSegmentFilter::default()
1065        };
1066
1067        match self
1068            ._api
1069            .get::<CollectionListSegment>(&endpoint, filter_params.build_payload())
1070        {
1071            Ok(collection) => MalchimpIter {
1072                builder: ListSegmentBuilder {
1073                    endpoint: endpoint.clone(),
1074                },
1075                data: collection.segments,
1076                cur_filters: filter_params.clone(),
1077                cur_it: 0,
1078                total_items: collection.total_items,
1079                api: self._api.clone(),
1080                endpoint: endpoint.clone(),
1081            },
1082            Err(e) => {
1083                error!( target: "mailchimp",  "Get List Segments: Response Error details: {:?}", e);
1084                MalchimpIter {
1085                    builder: ListSegmentBuilder {
1086                        endpoint: endpoint.clone(),
1087                    },
1088                    data: Vec::new(),
1089                    cur_filters: filter_params.clone(),
1090                    cur_it: 0,
1091                    total_items: 0,
1092                    api: self._api.clone(),
1093                    endpoint: endpoint.clone(),
1094                }
1095            }
1096        }
1097    }
1098
1099    ///
1100    /// Get Specific Segment
1101    ///
1102    pub fn get_specific_segment<'a>(&self, segment_id: &'a str) -> MailchimpResult<ListSegment> {
1103        // GET /lists/{list_id}/segments/{segment_id}
1104        let mut endpoint = self.get_base_endpoint();
1105        endpoint.push_str("/segments/");
1106
1107        match self
1108            ._api
1109            .get::<ListSegment>(&(endpoint.clone() + segment_id), HashMap::new())
1110        {
1111            Ok(data) => {
1112                let mut n_data = data;
1113                n_data.set_api(self._api.clone());
1114                n_data.set_endpoint(&endpoint.clone());
1115                Ok(n_data)
1116            }
1117            Err(e) => Err(e),
1118        }
1119    }
1120
1121    ///
1122    /// Delete a list from your Mailchimp account. If you delete a list,
1123    /// you’ll lose the list history—including subscriber activity, unsubscribes,
1124    /// complaints, and bounces. You’ll also lose subscribers’ email addresses,
1125    /// unless you exported and backed up your list.
1126    ///
1127    pub fn delete(&self) -> Option<MailchimpErrorType> {
1128        // DELETE /lists/{list_id}
1129        let endpoint = self.get_base_endpoint();
1130        match self
1131            ._api
1132            .post::<EmptyType, HashMap<String, String>>(endpoint.as_str(), HashMap::new())
1133        {
1134            Ok(_) => None,
1135            Err(e) => Some(e),
1136        }
1137    }
1138
1139    ///
1140    /// Update the settings for a specific list.
1141    ///
1142    pub fn update(&self, param: ListParam) -> MailchimpResult<ListType> {
1143        // PATCH /lists/{list_id}
1144        self._api
1145            .patch::<ListType, ListParam>(self.get_base_endpoint().as_str(), param)
1146    }
1147
1148    ///
1149    /// Get Endpoint
1150    ///
1151    fn get_base_endpoint(&self) -> String {
1152        String::from("lists/") + self.id.as_ref().unwrap().as_str()
1153    }
1154}
1155
1156///
1157/// List param for new List
1158///
1159#[derive(Serialize, Deserialize, Debug, Clone)]
1160pub struct ListParam {
1161    /// The name of the list.
1162    #[serde(default, skip_serializing_if = "Option::is_none")]
1163    pub name: Option<String>,
1164    /// Contact information displayed in campaign footers to comply with international spam laws.
1165    #[serde(default, skip_serializing_if = "Option::is_none")]
1166    pub contact: Option<ContactType>,
1167    /// The permission reminder for the list.
1168    #[serde(default, skip_serializing_if = "Option::is_none")]
1169    pub permission_reminder: Option<String>,
1170    /// Whether campaigns for this list use the Archive Bar in archives by default.
1171    #[serde(default, skip_serializing_if = "Option::is_none")]
1172    pub use_archive_bar: Option<bool>,
1173    /// Default values for campaigns created for this list.
1174    #[serde(default, skip_serializing_if = "Option::is_none")]
1175    pub campaign_defaults: Option<CampaignDefaultsType>,
1176    /// The email address to send subscribe notifications to.
1177    #[serde(default, skip_serializing_if = "Option::is_none")]
1178    pub notify_on_subscribe: Option<String>,
1179    /// The email address to send unsubscribe notifications to.
1180    #[serde(default, skip_serializing_if = "Option::is_none")]
1181    pub notify_on_unsubscribe: Option<String>,
1182    /// Whether the list supports multiple formats for emails. When set to true,
1183    /// subscribers can choose whether they want to receive HTML or plain-text
1184    /// emails. When set to false, subscribers will receive HTML emails,
1185    ///  with a plain-text alternative backup.
1186    #[serde(default, skip_serializing_if = "Option::is_none")]
1187    pub email_type_option: Option<bool>,
1188    /// Whether this list is public or private.
1189    #[serde(default, skip_serializing_if = "Option::is_none")]
1190    pub visibility: Option<String>,
1191    /// Whether or not to require the subscriber to confirm subscription via email.
1192    #[serde(default, skip_serializing_if = "Option::is_none")]
1193    pub double_optin: Option<bool>,
1194    /// Whether or not the list has marketing permissions (eg. GDPR) enabled.
1195    #[serde(default, skip_serializing_if = "Option::is_none")]
1196    pub marketing_permissions: Option<bool>,
1197}