lemon_bugsnag_rs 0.1.2

A library for interacting with the BugSnag error-reporting and sessions APIs.
Documentation
use chrono::{DateTime, Utc};
use serde::Serialize;

#[cfg_attr(docsrs, doc(cfg(feature = "optional-builders")))]
#[cfg(feature = "optional-builders")]
use crate::common::builder::error::BuilderError;

/// Struct corresponding to the `session_counts` key in the BugSnag session API
/// payload.
///
/// ```
/// use lemon_bugsnag_rs::session::payload::session_counts::session_count::SessionCount;
///
/// let session_count = SessionCount::default();
/// ```
#[derive(Clone, Debug, Default, Serialize, Eq, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct SessionCount {
    /// The times at which the session started
    pub started_at: DateTime<Utc>,
    /// The amount of sessions started within a timeframe
    pub sessions_started: u16,
}

#[cfg_attr(docsrs, doc(cfg(feature = "convenience-intos")))]
#[cfg(feature = "convenience-intos")]
impl Into<Vec<SessionCount>> for SessionCount {
    fn into(self) -> Vec<SessionCount> {
        [self].into()
    }
}

#[cfg_attr(docsrs, doc(cfg(feature = "optional-builders")))]
#[cfg(feature = "optional-builders")]
impl SessionCount {
    /// Retrieve an [SessionCountBuilder].
    ///
    /// ```
    /// use lemon_bugsnag_rs::session::payload::session_counts::session_count::SessionCount;
    ///
    /// let mut scb = SessionCount::builder();
    /// ```
    pub fn builder() -> SessionCountBuilder {
        SessionCountBuilder::default()
    }
}

/// Builder used to generate an [SessionCount] struct.
///
/// ```
/// use lemon_bugsnag_rs::session::payload::session_counts::session_count::SessionCount;
///
/// // Generally, you get the builder this way, rather than creating an
/// // AppBuilder struct manually.
/// let mut scb = SessionCount::builder();
/// ```
#[cfg_attr(docsrs, doc(cfg(feature = "optional-builders")))]
#[cfg(feature = "optional-builders")]
#[derive(Clone, Debug, Default)]
pub struct SessionCountBuilder {
    session_count: SessionCount,
    started_at: Option<DateTime<Utc>>,
    sessions_started: Option<u16>,
}

#[cfg_attr(docsrs, doc(cfg(feature = "optional-builders")))]
#[cfg(feature = "optional-builders")]
impl SessionCountBuilder {
    /// Set the started_at field of the SessionCount struct.
    ///
    /// ```
    /// use lemon_bugsnag_rs::session::payload::session_counts::session_count::SessionCount;
    /// use chrono::Utc;
    ///
    /// let timestamp = Utc::now();
    /// let mut scb = SessionCount::builder();
    ///
    /// // Give the started_at a value.
    /// scb.set_started_at(timestamp);
    ///
    /// // Unset the started_at.
    /// scb.set_started_at(None);
    /// ```
    pub fn set_started_at<'a>(
        &mut self,
        started_at: impl Into<Option<DateTime<Utc>>>,
    ) -> &mut Self {
        self.started_at = started_at.into().map(|item| item.into());

        self
    }

    /// Set the session_started field of the SessionCount struct.
    ///
    /// ```
    /// use lemon_bugsnag_rs::session::payload::session_counts::session_count::SessionCount;
    ///
    /// let mut scb = SessionCount::builder();
    ///
    /// // Give the session_started a value.
    /// scb.set_sessions_started(12);
    ///
    /// // Unset the session_started.
    /// scb.set_sessions_started(None);
    /// ```
    pub fn set_sessions_started(
        &mut self,
        sessions_started: impl Into<Option<u16>>,
    ) -> &mut Self {
        self.sessions_started = sessions_started.into();

        self
    }

    /// Generate an [SessionCount] struct using the options you set using the
    /// builder
    ///
    /// ```
    /// use lemon_bugsnag_rs::session::payload::session_counts::session_count::SessionCount;
    /// use chrono::Utc;
    ///
    /// let timestamp = Utc::now();
    /// let mut scb = SessionCount::builder();
    ///
    /// scb.set_started_at(timestamp)
    ///     .set_sessions_started(5);
    ///
    /// let session_counts = scb.build().unwrap();
    /// ```
    pub fn build(&mut self) -> Result<SessionCount, BuilderError> {
        let mut missing_fields = Vec::new();

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

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

        if missing_fields.len() > 0 {
            Err(BuilderError::MissingField {
                context: "session::SessionCountBuilder".to_string(),
                fields: missing_fields,
            })
        } else {
            self.session_count.started_at = self.started_at.clone().unwrap();
            self.session_count.sessions_started =
                self.sessions_started.clone().unwrap();

            Ok(self.session_count.clone())
        }
    }
}

#[cfg(test)]
mod test {
    #[test]
    #[cfg(feature = "optional-builders")]
    pub fn test_session_payload_session_count_builder() {
        use super::SessionCount;

        let reference_session_count = SessionCount {
            started_at: chrono::Utc::now(),
            sessions_started: 1,
        };

        let session_count = SessionCount::builder()
            .set_started_at(reference_session_count.started_at)
            .set_sessions_started(reference_session_count.sessions_started)
            .build()
            .unwrap();

        assert_eq!(session_count, reference_session_count);
    }
}