use serde::Serialize;
use super::{enums::RuntimeType, StackTrace};
#[derive(Clone, Debug, Default, Serialize, Eq, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Thread {
pub id: Option<String>,
pub name: Option<String>,
pub error_reporting_thread: Option<bool>,
pub stack_trace: Option<Vec<StackTrace>>,
pub state: Option<String>,
#[serde(rename(serialize = "type"))]
pub runtime_type: Option<RuntimeType>,
}
#[cfg_attr(docsrs, doc(cfg(feature = "optional-builders")))]
#[cfg(feature = "optional-builders")]
impl Thread {
pub fn builder() -> ThreadBuilder {
ThreadBuilder::default()
}
}
#[cfg_attr(docsrs, doc(cfg(feature = "convenience-intos")))]
#[cfg(feature = "convenience-intos")]
impl Into<Vec<Thread>> for Thread {
fn into(self) -> Vec<Thread> {
[self].into()
}
}
#[cfg_attr(docsrs, doc(cfg(feature = "convenience-intos")))]
#[cfg(feature = "convenience-intos")]
impl Into<Option<Vec<Thread>>> for Thread {
fn into(self) -> Option<Vec<Thread>> {
Some([self].into())
}
}
#[cfg_attr(docsrs, doc(cfg(feature = "optional-builders")))]
#[cfg(feature = "optional-builders")]
#[derive(Default)]
pub struct ThreadBuilder {
thread: Thread,
}
#[cfg_attr(docsrs, doc(cfg(feature = "optional-builders")))]
#[cfg(feature = "optional-builders")]
impl ThreadBuilder {
pub fn set_id<'a>(&mut self, id: impl Into<Option<&'a str>>) -> &mut Self {
self.thread.id = id.into().map(|item| item.into());
self
}
pub fn set_name<'a>(
&mut self,
name: impl Into<Option<&'a str>>,
) -> &mut Self {
self.thread.name = name.into().map(|item| item.into());
self
}
pub fn set_error_reporting_thread(
&mut self,
error_reporting_thread: impl Into<Option<bool>>,
) -> &mut Self {
self.thread.error_reporting_thread =
error_reporting_thread.into().map(|item| item.into());
self
}
pub fn set_stack_trace(
&mut self,
stack_trace: impl Into<Option<Vec<StackTrace>>>,
) -> &mut Self {
self.thread.stack_trace = stack_trace.into().map(|item| item.into());
self
}
pub fn set_state<'a>(
&mut self,
state: impl Into<Option<&'a str>>,
) -> &mut Self {
self.thread.state = state.into().map(|item| item.into());
self
}
pub fn set_runtime_type(
&mut self,
runtime_type: impl Into<Option<RuntimeType>>,
) -> &mut Self {
self.thread.runtime_type = runtime_type.into();
self
}
pub fn build(&self) -> Thread {
self.thread.clone()
}
}
#[cfg(test)]
mod test {
#[cfg(feature = "optional-builders")]
#[test]
pub fn test_error_payload_events_thread_builder() {
use super::Thread;
use crate::error::payload::events::enums::RuntimeType;
use crate::error::payload::events::{StackTrace, StackTraceCode};
let stack_trace_code: StackTraceCode = (&[
(10 as usize, "PRINT \"HELLO WORLD\""),
(20 as usize, "PRINT GOTO 10"),
][..])
.into();
let stack_trace = StackTrace {
file: "Filename".to_string(),
line_number: 12,
column_number: 24.into(),
method: "Function".to_string(),
in_project: true.into(),
code: stack_trace_code.clone().into(),
frame_address: "Frame Address".to_string().into(),
load_address: "Load Address".to_string().into(),
is_lr: true.into(),
is_pc: false.into(),
symbol_address: "Symbol Address".to_string().into(),
macho_file: "Macho File".to_string().into(),
macho_load_address: "Macho Load Address".to_string().into(),
macho_uuid: "Macho UUID".to_string().into(),
macho_vm_address: "Macho VM Adress".to_string().into(),
code_identifier: "Code Identifier".to_string().into(),
};
let test_thread = Thread {
id: "2".to_string().into(),
name: "Thread name".to_string().into(),
error_reporting_thread: true.into(),
stack_trace: vec![stack_trace].into(),
state: "State".to_string().into(),
runtime_type: RuntimeType::BrowserJs.into(),
};
let thread = Thread::builder()
.set_id(test_thread.id.as_deref())
.set_name(test_thread.name.as_deref())
.set_error_reporting_thread(
test_thread.error_reporting_thread.clone(),
)
.set_stack_trace(test_thread.stack_trace.clone())
.set_state(test_thread.state.as_deref())
.set_runtime_type(test_thread.runtime_type.clone())
.build();
assert_eq!(thread, test_thread);
}
}