#![allow(elided_named_lifetimes)]
#![allow(missing_docs)]
#![allow(unused_imports)]
#![allow(clippy::needless_lifetimes)]
#![allow(clippy::too_many_arguments)]
#![cfg_attr(docsrs, feature(doc_cfg))]
#[cfg(feature = "requests")]
pub mod candidate_applications;
#[cfg(feature = "requests")]
pub mod candidates;
#[cfg(feature = "requests")]
pub mod companies;
#[cfg(feature = "requests")]
pub mod compensations;
#[cfg(feature = "requests")]
pub mod custom_fields;
#[cfg(feature = "requests")]
pub mod custom_object_fields;
#[cfg(feature = "requests")]
pub mod custom_object_records;
#[cfg(feature = "requests")]
pub mod custom_objects;
#[cfg(feature = "requests")]
pub mod departments;
#[cfg(feature = "requests")]
pub mod employment_types;
#[cfg(feature = "requests")]
pub mod entitlements;
#[cfg(feature = "requests")]
pub mod job;
#[cfg(feature = "requests")]
pub mod job_requisitions;
#[cfg(feature = "requests")]
pub mod leave_balances;
#[cfg(feature = "requests")]
pub mod leave_requests;
#[cfg(feature = "requests")]
pub mod leave_types;
#[cfg(feature = "requests")]
pub mod legal_entities;
#[cfg(feature = "requests")]
pub mod me;
mod methods;
#[cfg(feature = "requests")]
pub mod object_categories;
#[cfg(feature = "requests")]
pub mod shift_inputs;
#[cfg(feature = "requests")]
pub mod teams;
#[cfg(test)]
mod tests;
#[cfg(feature = "requests")]
pub mod time_entries;
#[cfg(feature = "requests")]
pub mod tracks_and_levels;
pub mod types;
#[cfg(feature = "requests")]
pub mod users;
pub mod utils;
#[cfg(feature = "requests")]
pub mod work_locations;
#[cfg(feature = "requests")]
pub mod workers;
#[cfg(feature = "requests")]
use std::env;
#[cfg(not(target_arch = "wasm32"))]
#[cfg(feature = "requests")]
static APP_USER_AGENT: &str = concat!(env!("CARGO_PKG_NAME"), ".rs/", env!("CARGO_PKG_VERSION"),);
#[derive(Clone, Debug)]
#[cfg(feature = "requests")]
pub struct Client {
token: String,
base_url: String,
#[cfg(feature = "retry")]
client: reqwest_middleware::ClientWithMiddleware,
#[cfg(feature = "retry")]
#[cfg(not(target_arch = "wasm32"))]
#[allow(dead_code)]
client_http1_only: reqwest_middleware::ClientWithMiddleware,
#[cfg(not(feature = "retry"))]
client: reqwest::Client,
#[cfg(not(feature = "retry"))]
#[cfg(not(target_arch = "wasm32"))]
#[allow(dead_code)]
client_http1_only: reqwest::Client,
}
#[cfg(feature = "retry")]
#[cfg(feature = "requests")]
pub struct RequestBuilder(pub reqwest_middleware::RequestBuilder);
#[cfg(not(feature = "retry"))]
#[cfg(feature = "requests")]
pub struct RequestBuilder(pub reqwest::RequestBuilder);
#[cfg(feature = "requests")]
impl Client {
#[tracing::instrument(skip(token))]
#[cfg(not(target_arch = "wasm32"))]
pub fn new_from_reqwest<T>(
token: T,
builder_http: reqwest::ClientBuilder,
builder_websocket: reqwest::ClientBuilder,
) -> Self
where
T: ToString + std::fmt::Debug,
{
#[cfg(feature = "retry")]
{
let retry_policy =
reqwest_retry::policies::ExponentialBackoff::builder().build_with_max_retries(3);
match (builder_http.build(), builder_websocket.build()) {
(Ok(c), Ok(c1)) => {
let client = reqwest_middleware::ClientBuilder::new(c)
.with(reqwest_tracing::TracingMiddleware::default())
.with(reqwest_conditional_middleware::ConditionalMiddleware::new(
reqwest_retry::RetryTransientMiddleware::new_with_policy(retry_policy),
|req: &reqwest::Request| req.try_clone().is_some(),
))
.build();
let client_http1_only = reqwest_middleware::ClientBuilder::new(c1)
.with(reqwest_tracing::TracingMiddleware::default())
.with(reqwest_conditional_middleware::ConditionalMiddleware::new(
reqwest_retry::RetryTransientMiddleware::new_with_policy(retry_policy),
|req: &reqwest::Request| req.try_clone().is_some(),
))
.build();
Client {
token: token.to_string(),
base_url: "https://rest.ripplingapis.com".to_string(),
client,
client_http1_only,
}
}
(Err(e), _) | (_, Err(e)) => panic!("creating reqwest client failed: {:?}", e),
}
}
#[cfg(not(feature = "retry"))]
{
match (builder_http.build(), builder_websocket.build()) {
(Ok(c), Ok(c1)) => Client {
token: token.to_string(),
base_url: "https://rest.ripplingapis.com".to_string(),
client: c,
client_http1_only: c1,
},
(Err(e), _) | (_, Err(e)) => panic!("creating reqwest client failed: {:?}", e),
}
}
}
#[tracing::instrument(skip(token))]
#[cfg(target_arch = "wasm32")]
pub fn new_from_reqwest<T>(token: T, builder_http: reqwest::ClientBuilder) -> Self
where
T: ToString + std::fmt::Debug,
{
#[cfg(feature = "retry")]
{
let retry_policy =
reqwest_retry::policies::ExponentialBackoff::builder().build_with_max_retries(3);
match builder_http.build() {
Ok(c) => {
let client = reqwest_middleware::ClientBuilder::new(c)
.with(reqwest_tracing::TracingMiddleware::default())
.with(reqwest_conditional_middleware::ConditionalMiddleware::new(
reqwest_retry::RetryTransientMiddleware::new_with_policy(retry_policy),
|req: &reqwest::Request| req.try_clone().is_some(),
))
.build();
Client {
token: token.to_string(),
base_url: "https://rest.ripplingapis.com".to_string(),
client,
}
}
Err(e) => panic!("creating reqwest client failed: {:?}", e),
}
}
#[cfg(not(feature = "retry"))]
{
match builder_http.build() {
Ok(c) => Client {
token: token.to_string(),
base_url: "https://rest.ripplingapis.com".to_string(),
client: c,
},
Err(e) => panic!("creating reqwest client failed: {:?}", e),
}
}
}
#[tracing::instrument(skip(token))]
pub fn new<T>(token: T) -> Self
where
T: ToString + std::fmt::Debug,
{
#[cfg(not(target_arch = "wasm32"))]
let client = reqwest::Client::builder()
.user_agent(APP_USER_AGENT)
.timeout(std::time::Duration::from_secs(600))
.connect_timeout(std::time::Duration::from_secs(60));
#[cfg(target_arch = "wasm32")]
let client = reqwest::Client::builder();
#[cfg(not(target_arch = "wasm32"))]
let client_http1 = reqwest::Client::builder()
.user_agent(APP_USER_AGENT)
.timeout(std::time::Duration::from_secs(600))
.connect_timeout(std::time::Duration::from_secs(60))
.http1_only();
#[cfg(not(target_arch = "wasm32"))]
return Self::new_from_reqwest(token, client, client_http1);
#[cfg(target_arch = "wasm32")]
Self::new_from_reqwest(token, client)
}
#[tracing::instrument]
pub fn set_base_url<H>(&mut self, base_url: H)
where
H: Into<String> + std::fmt::Display + std::fmt::Debug,
{
self.base_url = base_url.to_string().trim_end_matches('/').to_string();
}
#[tracing::instrument]
pub fn new_from_env() -> Self {
let token = env::var("RIPPLING_API_TOKEN").expect("must set RIPPLING_API_TOKEN");
let base_url =
env::var("RIPPLING_HOST").unwrap_or("https://rest.ripplingapis.com".to_string());
let mut c = Client::new(token);
c.set_base_url(base_url);
c
}
#[tracing::instrument]
pub async fn request_raw(
&self,
method: reqwest::Method,
uri: &str,
body: Option<reqwest::Body>,
) -> anyhow::Result<RequestBuilder> {
let u = if uri.starts_with("https://") || uri.starts_with("http://") {
uri.to_string()
} else {
format!("{}/{}", self.base_url, uri.trim_start_matches('/'))
};
let mut req = self.client.request(method, &u);
req = req.bearer_auth(&self.token);
req = req.header(
reqwest::header::ACCEPT,
reqwest::header::HeaderValue::from_static("application/json"),
);
req = req.header(
reqwest::header::CONTENT_TYPE,
reqwest::header::HeaderValue::from_static("application/json"),
);
if let Some(body) = body {
req = req.body(body);
}
Ok(RequestBuilder(req))
}
pub fn candidate_applications(&self) -> candidate_applications::CandidateApplications {
candidate_applications::CandidateApplications::new(self.clone())
}
pub fn candidates(&self) -> candidates::Candidates {
candidates::Candidates::new(self.clone())
}
pub fn companies(&self) -> companies::Companies {
companies::Companies::new(self.clone())
}
pub fn compensations(&self) -> compensations::Compensations {
compensations::Compensations::new(self.clone())
}
pub fn custom_fields(&self) -> custom_fields::CustomFields {
custom_fields::CustomFields::new(self.clone())
}
pub fn custom_object_fields(&self) -> custom_object_fields::CustomObjectFields {
custom_object_fields::CustomObjectFields::new(self.clone())
}
pub fn custom_object_records(&self) -> custom_object_records::CustomObjectRecords {
custom_object_records::CustomObjectRecords::new(self.clone())
}
pub fn custom_objects(&self) -> custom_objects::CustomObjects {
custom_objects::CustomObjects::new(self.clone())
}
pub fn departments(&self) -> departments::Departments {
departments::Departments::new(self.clone())
}
pub fn employment_types(&self) -> employment_types::EmploymentTypes {
employment_types::EmploymentTypes::new(self.clone())
}
pub fn entitlements(&self) -> entitlements::Entitlements {
entitlements::Entitlements::new(self.clone())
}
pub fn job(&self) -> job::Job {
job::Job::new(self.clone())
}
pub fn job_requisitions(&self) -> job_requisitions::JobRequisitions {
job_requisitions::JobRequisitions::new(self.clone())
}
pub fn leave_balances(&self) -> leave_balances::LeaveBalances {
leave_balances::LeaveBalances::new(self.clone())
}
pub fn leave_requests(&self) -> leave_requests::LeaveRequests {
leave_requests::LeaveRequests::new(self.clone())
}
pub fn leave_types(&self) -> leave_types::LeaveTypes {
leave_types::LeaveTypes::new(self.clone())
}
pub fn legal_entities(&self) -> legal_entities::LegalEntities {
legal_entities::LegalEntities::new(self.clone())
}
pub fn me(&self) -> me::Me {
me::Me::new(self.clone())
}
pub fn object_categories(&self) -> object_categories::ObjectCategories {
object_categories::ObjectCategories::new(self.clone())
}
pub fn shift_inputs(&self) -> shift_inputs::ShiftInputs {
shift_inputs::ShiftInputs::new(self.clone())
}
pub fn teams(&self) -> teams::Teams {
teams::Teams::new(self.clone())
}
pub fn time_entries(&self) -> time_entries::TimeEntries {
time_entries::TimeEntries::new(self.clone())
}
pub fn tracks_and_levels(&self) -> tracks_and_levels::TracksAndLevels {
tracks_and_levels::TracksAndLevels::new(self.clone())
}
pub fn users(&self) -> users::Users {
users::Users::new(self.clone())
}
pub fn work_locations(&self) -> work_locations::WorkLocations {
work_locations::WorkLocations::new(self.clone())
}
pub fn workers(&self) -> workers::Workers {
workers::Workers::new(self.clone())
}
}