use ureq::AgentBuilder;
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,
},
ureq::client::blocking::UreqSessionSync,
},
};
pub struct ClientBuilderUreqSessionSync {
pub client_builder: AgentBuilder,
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<UreqSessionSync, ErrorStack>
for ClientBuilderUreqSessionSync
{
fn build(mut self) -> Result<UreqSessionSync, 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 url = Cobbler::cobble(self.options.clone())?;
let mut request = self.client_builder.build().post(url.as_str());
match self.options.headers {
Some(headers) => {
for (header, value) in headers.into_iter() {
request = request.set(header.as_str(), value.as_str());
}
}
None => (),
};
let payload = Payload {
notifier: self.notifier.unwrap(),
app: self.app,
device: self.device,
sessions: self.sessions,
session_counts: self.session_counts,
};
Ok(UreqSessionSync { url, request, payload })
} else {
Err(error_stack)
}
}
}