lemon_bugsnag_rs 0.1.2

A library for interacting with the BugSnag error-reporting and sessions APIs.
Documentation
use ureq::AgentBuilder;

use crate::{
    common::{
        builder::{builder_options::BuilderOptions, error::BuilderError},
        cobbler::Cobbler,
        error::Error,
        traits::backend_builder_trait_sync::BackendBuilderTraitSync,
    },
    error::{
        payload::{events::Event, notifier::Notifier, Payload},
        ureq::client::blocking::UreqErrorSync,
    },
};

/// The client builder for ureq containing information needed to build the
/// [UreqErrorSync] which sends the synchronous request to Bugsnag's error
/// reporting API
///
/// ```
/// use lemon_bugsnag_rs::common::builder::client_builder::ClientBuilder;
/// use lemon_bugsnag_rs::common::traits::decider_trait_sync::DeciderTraitSync;
///
/// let mut error_builder = ClientBuilder::error();
///
/// let configured_builder = error_builder.configure(
///     "Fake API Key",
///     "Doctest configure example error class",
///     "It's not really an error, per se...",
///     "ErrorClientBuilder documentation test notifier",
///     "1.0.0",
///     "Doctest app type",
///     "Production, of course"
/// );
///
/// // This is the client_builder, which will be used to build the synchronous
/// // client that sends the request to Bugsnag's Error-Reporting API
/// let client_builder = configured_builder.ureq();
/// ```
pub struct ClientBuilderUreqErrorSync {
    /// Ureq backend client builder that builds the client which sends
    /// synchronous requests to Bugsnag Error reporting API
    pub client_builder: AgentBuilder,
    /// Options struct common to all BugSnag client builders in this library.
    pub(crate) options: BuilderOptions,
    /// The API Key associated with the project. Informs Bugsnag which project
    /// has generated this error.
    pub(crate) api_key: Option<String>,
    /// The version number of the payload. The Bugsnag-Payload-Version header
    /// should be included as well, for compatibility reasons.
    pub(crate) payload_version: String,
    /// Describes the notifier itself. These properties are used within Bugsnag
    /// to track error rates from a notifier.
    pub(crate) notifier: Option<Notifier>,
    /// An array of error events Bugsnag is notified of. A notifier can choose
    /// to group notices into an array to minimize network traffic, or notifies
    /// Bugsnag each time an event occurs. Should contain at least 1 event.
    pub(crate) events: Option<Vec<Event>>,
}

impl BackendBuilderTraitSync<UreqErrorSync, Error>
    for ClientBuilderUreqErrorSync
{
    /// Builds the ureq client that sends synchronous requests after checking
    /// for missing fields needed to properly send the requests.
    ///
    /// ```
    /// use lemon_bugsnag_rs::common::builder::client_builder::ClientBuilder;
    /// use lemon_bugsnag_rs::common::traits::decider_trait_sync::DeciderTraitSync;
    /// use lemon_bugsnag_rs::common::traits::backend_builder_trait_sync::BackendBuilderTraitSync;
    ///
    /// let mut error_builder = ClientBuilder::error();
    ///
    /// let configured_builder = error_builder.configure(
    ///     "Fake API Key",
    ///     "Doctest configure example error class",
    ///     "It's not really an error, per se...",
    ///     "ErrorClientBuilder documentation test notifier",
    ///     "1.0.0",
    ///     "Doctest app type",
    ///     "Production, of course"
    /// );
    ///
    /// let client_builder = configured_builder.ureq().build().unwrap();
    /// ```
    fn build(self) -> Result<UreqErrorSync, Error> {
        let mut missing_fields: Vec<String> = Vec::new();

        if self.notifier.is_none() {
            missing_fields.push("notifier".to_string());
        }

        if self.events.is_none() {
            missing_fields.push("events".to_string());
        }

        if missing_fields.len() == 0 {
            let url = Cobbler::cobble(self.options.clone())?;
            let mut request = self.client_builder.build().post(url.as_str());

            match self.options.headers {
                Some(headers) => {
                    for (header, value) in headers.into_iter() {
                        request = request.set(header.as_str(), value.as_str());
                    }
                }
                None => (),
            };

            let payload = Payload {
                api_key: self.api_key,
                payload_version: self.payload_version,
                notifier: self.notifier.unwrap(),
                events: self.events.unwrap(),
            };

            Ok(UreqErrorSync { url, request, payload })
        } else {
            Err(BuilderError::MissingField {
                context: "BackendBuilderTrait<UreqErrorSync, Error>"
                    .to_string(),
                fields: missing_fields,
            }
            .into())
        }
    }
}