yelp-fusion-rs 0.1.1

A Rust library for the Yelp Fusion API.
Documentation
use crate::endpoints::{BusinessSearchPayload, BusinessSearchPayloadError};
use crate::models::{Attribute, Coordinates, PriceType, SortBy};
use std::collections::HashSet;

#[derive(Debug, Clone, Default)]
pub struct BusinessSearchPayloadBuilder {
    /// Search term, for example "food" or "restaurants".
    ///
    /// The term may also be business names, such as "Starbucks".
    /// If term is not included the endpoint will default to searching across businesses from a small number of popular categories.
    pub term: Option<String>,

    /// Required if either latitude or longitude is not provided.
    ///
    /// This string indicates the geographic area to be used when searching for businesses.
    /// Examples: "New York City", "NYC", "350 5th Ave, New York, NY 10118".
    ///
    /// Businesses returned in the response may not be strictly within the specified location.
    pub location: Option<String>,

    /// Required if location is not provided.
    ///
    /// Latitude and longitude of the location you want to search nearby.
    pub coordinates: Option<Coordinates>,

    /// A suggested search radius in meters.
    ///
    /// This field is used as a suggestion to the search.
    /// The actual search radius may be lower than the suggested radius in dense urban areas, and higher in regions of less business density.
    /// If the specified value is too large, a AREA_TOO_LARGE error may be returned.
    /// The max value is 40000 meters (about 25 miles).
    pub radius: Option<usize>,

    /// Categories to filter the search results with.
    ///
    /// See the list of [supported categories](https://www.yelp.com/developers/documentation/v3/all_category_list).
    /// The category filter can be a list of comma delimited categories.
    /// For example, "bars,french" will filter by Bars OR French.
    /// The category identifier should be used (for example "discgolf", not "Disc Golf").
    pub categories: Option<Vec<String>>,

    /// Specify the locale into which to localize the business information.
    ///
    /// See the list of [supported locales](https://www.yelp.com/developers/documentation/v3/supported_locales).
    /// Defaults to `"en_US"`.
    pub locale: Option<String>,

    /// Number of business results to return.
    ///
    /// By default, it will return 20.
    /// Maximum is 50.
    pub limit: Option<usize>,

    /// Offset the list of returned business results by this amount.
    pub offset: Option<usize>,

    /// Suggestion to the search algorithm that the results be sorted by one of the these modes:
    /// best_match, rating, review_count or distance.
    ///
    /// The default is best_match.
    /// Note that specifying the sort_by is a suggestion (not strictly enforced) to Yelp's search,
    /// which considers multiple input parameters to return the most relevant results.
    ///
    /// For example, the rating sort is not strictly sorted by the rating value, but by an adjusted
    /// rating value that takes into account the number of ratings, similar to a Bayesian average.
    /// This is to prevent skewing results to businesses with a single review.
    pub sort_by: Option<SortBy>,

    /// Pricing levels to filter the search result with: 1 = $, 2 = $$, 3 = $$$, 4 = $$$$.
    ///
    /// The price filter can be a list of comma delimited pricing levels.
    /// For example, "1, 2, 3" will filter the results to show the ones that are $, $$, or $$$.
    pub price: Option<HashSet<PriceType>>,

    /// Default to false.
    /// When set to true, only return the businesses open now.
    ///
    /// Notice that open_at and open_now cannot be used together.
    pub open_now: Option<bool>,

    /// An integer representing the Unix time in the same timezone of the search location.
    ///
    /// If specified, it will return business open at the given time.
    ///
    /// Notice that open_at and open_now cannot be used together.
    pub open_at: Option<usize>,

    /// Try these additional filters to return specific search results!
    ///
    /// You can combine multiple attributes by providing a comma separated like "attribute1,attribute2".
    /// If multiple attributes are used, only businesses that satisfy ALL attributes will be returned
    /// in search results.
    /// For example, the attributes "hot_and_new,request_a_quote" will return businesses that are Hot
    /// and New AND offer Request a Quote.
    pub attributes: Option<HashSet<Attribute>>,
}

impl BusinessSearchPayloadBuilder {
    pub fn term(&mut self, term: String) -> &mut Self {
        self.term = Some(term);
        self
    }

    pub fn location(&mut self, location: String) -> &mut Self {
        self.location = Some(location);
        self
    }

    pub fn coordinates(&mut self, coordinates: Coordinates) -> &mut Self {
        self.coordinates = Some(coordinates);
        self
    }

    pub fn radius(&mut self, radius: usize) -> &mut Self {
        self.radius = Some(radius);
        self
    }

    pub fn categories(&mut self, categories: Vec<String>) -> &mut Self {
        self.categories = Some(categories);
        self
    }

    pub fn locale(&mut self, locale: String) -> &mut Self {
        self.locale = Some(locale);
        self
    }

    pub fn limit(&mut self, limit: usize) -> &mut Self {
        self.limit = Some(limit);
        self
    }

    pub fn offset(&mut self, offset: usize) -> &mut Self {
        self.offset = Some(offset);
        self
    }

    pub fn sort_by(&mut self, sort_by: SortBy) -> &mut Self {
        self.sort_by = Some(sort_by);
        self
    }

    pub fn price(&mut self, price: HashSet<PriceType>) -> &mut Self {
        self.price = Some(price);
        self
    }

    pub fn open_now(&mut self, open_now: bool) -> &mut Self {
        self.open_now = Some(open_now);
        self
    }

    pub fn open_at(&mut self, open_at: usize) -> &mut Self {
        self.open_at = Some(open_at);
        self
    }

    pub fn attributes(&mut self, attributes: HashSet<Attribute>) -> &mut Self {
        self.attributes = Some(attributes);
        self
    }

    /// # Errors
    ///
    /// Returns `BusinessSearchPayloadError::BothLocationAndLatLongSet` if both `location` and
    /// `coordinates` are set. Only one or the other can be set.
    ///
    /// Returns `BusinessSearchPayloadError::RadiusTooLarge` if `radius` is over `40,000` meters
    /// (~25 miles).
    ///
    /// Returns `BusinessSearchPayloadError::LimitTooLarge` if `limit` is over `50`.
    ///
    /// Returns `BusinessSearchPayloadError::BothOpenNowAndOpenAtSet` if both `open_now` and
    /// `open_at` are set. Only one of the other can be set.
    pub fn build(&self) -> Result<BusinessSearchPayload, BusinessSearchPayloadError> {
        BusinessSearchPayload::new(
            self.term.clone(),
            self.location.clone(),
            self.coordinates,
            self.radius,
            self.categories.clone(),
            self.locale.clone(),
            self.limit,
            self.offset,
            self.sort_by,
            self.price.clone(),
            self.open_now,
            self.open_at,
            self.attributes.clone(),
        )
    }
}