whos_your_daddy_common 0.1.3

Common source code for the Who's Your Daddy projects, like the Enumerator and Presenter.
Documentation
//! Defines the `Official` structure along with supporting enums that describe
//! government levels and branches.
use chrono::NaiveDate;
use serde::{Deserialize, Serialize};
use uuid::Uuid;

/// Represents the level of government for an elected official.
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub enum GovernmentLevel {
    /// Federal level (e.g., President, Senators, Representatives)
    Federal,
    /// State level (e.g., Governor, State Legislators)
    State,
    /// County level (e.g., County Commissioners, Sheriffs)
    County,
    /// Municipal level (e.g., Mayors, City Council Members)
    Municipal,
    /// Special districts (e.g., School Board, Water District)
    SpecialDistrict,
}

/// Represents the branch of government.
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub enum Branch {
    /// Executive branch
    Executive,
    /// Legislative branch
    Legislative,
    /// Judicial branch
    Judicial,
}

/// Represents a single term of office for an `Official`.
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct Term {
    /// The start date of the term in `YYYY-MM-DD` format.
    pub start_date: NaiveDate,

    /// Sources of information for the `start_date` field.
    pub start_date_sources: Vec<String>,

    /// The end date of the term in `YYYY-MM-DD` format.
    /// `None` indicates the term is ongoing.
    pub end_date: Option<NaiveDate>,

    /// Sources of information for the `end_date` field.
    pub end_date_sources: Vec<String>,

    /// The title of the office held during this term.
    /// (e.g., "U.S. Senator", "Governor", "Mayor").
    pub office_title: String,

    /// Sources of information for the `office_title` field.
    pub office_title_sources: Vec<String>,

    /// The level of government for this term.
    pub level: GovernmentLevel,

    /// Sources of information for the `level` field.
    pub level_sources: Vec<String>,

    /// The location where the `Official` served during this term.
    /// (e.g., "CA", "New York City", "District 5").
    pub location: String,

    /// Sources of information for the `location` field.
    pub location_sources: Vec<String>,

    /// The registered political party during this term.
    /// (e.g., "Democratic", "Republican", "Independent").
    pub political_party: String,

    /// Sources of information for the `political_party` field.
    pub political_party_sources: Vec<String>,
}

/// The `Official` structure maintains data about a single government official.
/// This struct is designed to match the definition of a row in the backing
/// PostgreSQL database's `people` table.
#[derive(Debug, Deserialize, Serialize)]
#[cfg_attr(feature = "postgres", derive(sqlx::FromRow))]
pub struct Official {
    /// The `birth` field indicates the `Official`'s date of birth in `YYYY-MM-DD`
    /// format.
    pub birth: NaiveDate,

    /// Sources of information for the `birth` field.
    pub birth_sources: Vec<String>,

    /// This field indicates the individual's first name.
    pub first_name: String,

    /// Sources of information for the `first_name` field.
    pub first_name_sources: Vec<String>,

    /// Unique identifier for the official
    pub id: Uuid,

    /// This field indicates the individual's last name.
    pub last_name: String,

    /// Sources of information for the `last_name` field.
    pub last_name_sources: Vec<String>,

    /// This field indicates the individual's middle name, which may or may
    /// not exist.
    pub middle_name: Option<String>,

    /// Sources of information for the `middle_name` field.
    pub middle_name_sources: Vec<String>,

    /// A list of terms of office held by this official.
    pub terms: Vec<Term>,
} // Official

impl Official {
    /// This function constructs a `String` representing the `Official`'s full
    /// name from the `Official`'s name members.
    ///
    /// # Returns
    /// This function returns a `String` object containing the result of
    /// concatenating the `Official`'s name members.
    pub fn get_full_name(&self) -> String {
        let middle_name_string = match &self.middle_name {
            Some(name) => {
                // If there's a middle name we will construct the string to
                // include a trailing space so that the format macro below
                // will still build the name nicely.
                format!("{0} ", name)
            }
            None => String::from(""),
        };

        // Build and return the name string.  The second and third
        // names are squished together so that if there is no middle name
        // the first and last names are not separated by two spaces, only
        // one.
        format!(
            "{0} {1}{2}",
            self.first_name, middle_name_string, self.last_name
        )
    } // get_full_name
}

#[cfg(test)]
mod tests {
    use super::*;

    /// This function tests the `Official` struct's `get_full_name` method.
    #[test]
    fn test_official_get_full_name() {
        let official = Official {
            birth: NaiveDate::from_ymd_opt(1997, 8, 6).unwrap(),
            birth_sources: Vec::new(),
            // branch: Some(Branch::Executive),
            first_name: String::from("Austin"),
            first_name_sources: Vec::new(),
            id: Uuid::new_v4(),
            last_name: String::from("Farrell"),
            last_name_sources: Vec::new(),
            // level: Some(GovernmentLevel::Federal),
            middle_name: Some(String::from("Michael")),
            middle_name_sources: Vec::new(),
            terms: Vec::new(),
        };

        assert_eq!(
            official.get_full_name(),
            String::from("Austin Michael Farrell")
        );

        let official = Official {
            birth: NaiveDate::from_ymd_opt(1997, 8, 6).unwrap(),
            birth_sources: Vec::new(),
            // branch: Some(Branch::Legislative),
            first_name: String::from("Austin"),
            first_name_sources: Vec::new(),
            id: Uuid::new_v4(),
            last_name: String::from("Farrell"),
            last_name_sources: Vec::new(),
            // level: Some(GovernmentLevel::State),
            middle_name: None,
            middle_name_sources: Vec::new(),
            terms: Vec::new(),
        };

        assert_eq!(official.get_full_name(), String::from("Austin Farrell"));
    } // test_official_get_full_name
}