use reqwest::{
blocking::ClientBuilder as ClientBuilderSync,
header::{HeaderMap, HeaderName, HeaderValue},
};
use crate::{
common::{
builder::{builder_options::BuilderOptions, error::BuilderError},
cobbler::Cobbler,
error::ErrorStack,
traits::backend_builder_trait_sync::BackendBuilderTraitSync,
},
session::{
payload::{
device::Device, notifier::Notifier,
session_counts::session_count::SessionCount, sessions::Session,
App, Payload,
},
reqwest::client::blocking::ReqwestSessionSync,
},
};
pub struct ClientBuilderReqwestSessionSync {
pub client_builder: ClientBuilderSync,
pub(crate) options: BuilderOptions,
pub(crate) api_key: Option<String>,
pub(crate) payload_version: String,
pub(crate) notifier: Option<Notifier>,
pub(crate) app: Option<App>,
pub(crate) device: Option<Device>,
pub(crate) sessions: Option<Vec<Session>>,
pub(crate) session_counts: Option<Vec<SessionCount>>,
}
impl BackendBuilderTraitSync<ReqwestSessionSync, ErrorStack>
for ClientBuilderReqwestSessionSync
{
fn build(mut self) -> Result<ReqwestSessionSync, ErrorStack> {
let mut error_stack = ErrorStack::default();
let mut missing_fields: Vec<String> = Vec::new();
let headers = self.options.headers.as_mut().unwrap();
if self.api_key.is_some() {
headers.insert(
"Bugsnag-Api-Key".to_string(),
self.api_key.clone().unwrap(),
);
}
headers.insert(
"Bugsnag-Payload-Version".into(),
self.payload_version.clone(),
);
if !headers.contains_key("Bugsnag-Api-Key") {
missing_fields.push("api_key".to_string());
}
if self.notifier.is_none() {
missing_fields.push("notifier".to_string());
}
if missing_fields.len() > 0 {
error_stack.errors.push(
BuilderError::MissingField {
context:
"BackendBuilderTrait<ReqwestSessionAsync, ErrorStack>"
.to_string(),
fields: missing_fields,
}
.into(),
);
}
if self.sessions.is_some() && self.session_counts.is_some() {
let mut conflicting_fields: Vec<String> = Vec::new();
conflicting_fields.push("sessions".to_string());
conflicting_fields.push("session_counts".to_string());
error_stack.errors.push(
BuilderError::ConflictingField {
context:
"BackendBuilderTrait<ReqwestSessionAsync, ErrorStack>"
.to_string(),
fields: conflicting_fields,
}
.into(),
);
}
match &self.app {
Some(app) => {
if app.version_code.is_some() && app.bundle_version.is_some() {
let mut conflicting_fields: Vec<String> = Vec::new();
conflicting_fields.push("app.version_code".to_string());
conflicting_fields.push("app.bundle_version".to_string());
error_stack.errors.push(
BuilderError::ConflictingField {
context: "BackendBuilderTrait<ReqwestSessionAsync, ErrorStack>".to_string(),
fields: conflicting_fields,
}
.into(),
);
}
}
None => (),
}
if error_stack.errors.len() == 0 {
let client = self
.client_builder
.default_headers(
self.options
.headers
.as_ref()
.unwrap()
.into_iter()
.map(|(header_name, header_value)| {
(
HeaderName::from_bytes(header_name.as_bytes())
.unwrap(),
HeaderValue::from_str(&header_value).unwrap(),
)
})
.collect::<HeaderMap>(),
)
.build()?;
let payload = Payload {
notifier: self.notifier.unwrap(),
app: self.app,
device: self.device,
sessions: self.sessions,
session_counts: self.session_counts,
};
let url = Cobbler::cobble(self.options)?;
Ok(ReqwestSessionSync { url, client, payload })
} else {
Err(error_stack)
}
}
}