use std::borrow::Cow;
use std::cmp;
use std::fmt;
use std::iter::FromIterator;
use std::net::{AddrParseError, IpAddr};
use std::ops;
use std::str;
use ::debugid::DebugId;
use chrono::{DateTime, Utc};
use failure::Fail;
use serde::Serializer;
use serde::{Deserialize, Serialize};
use url::Url;
use url_serde;
use uuid::Uuid;
use crate::utils::ts_seconds_float;
pub mod value {
    pub use serde_json::value::{from_value, to_value, Index, Map, Number, Value};
}
pub mod map {
    pub use std::collections::btree_map::{BTreeMap as Map, *};
}
pub mod debugid {
    pub use debugid::{BreakpadFormat, DebugId, ParseDebugIdError};
}
pub use self::value::Value;
pub use self::map::Map;
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct Values<T> {
    
    pub values: Vec<T>,
}
impl<T> Values<T> {
    
    pub fn new() -> Values<T> {
        Values { values: Vec::new() }
    }
    
    pub fn is_empty(&self) -> bool {
        self.values.is_empty()
    }
}
impl<T> Default for Values<T> {
    fn default() -> Self {
        
        Values::new()
    }
}
impl<T> From<Vec<T>> for Values<T> {
    fn from(values: Vec<T>) -> Self {
        Values { values }
    }
}
impl<T> AsRef<[T]> for Values<T> {
    fn as_ref(&self) -> &[T] {
        &self.values
    }
}
impl<T> AsMut<Vec<T>> for Values<T> {
    fn as_mut(&mut self) -> &mut Vec<T> {
        &mut self.values
    }
}
impl<T> ops::Deref for Values<T> {
    type Target = [T];
    fn deref(&self) -> &Self::Target {
        &self.values
    }
}
impl<T> ops::DerefMut for Values<T> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.values
    }
}
impl<T> FromIterator<T> for Values<T> {
    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
        Vec::<T>::from_iter(iter).into()
    }
}
impl<T> Extend<T> for Values<T> {
    fn extend<I>(&mut self, iter: I)
    where
        I: IntoIterator<Item = T>,
    {
        self.values.extend(iter)
    }
}
impl<'a, T> IntoIterator for &'a mut Values<T> {
    type Item = <&'a mut Vec<T> as IntoIterator>::Item;
    type IntoIter = <&'a mut Vec<T> as IntoIterator>::IntoIter;
    fn into_iter(self) -> Self::IntoIter {
        (&mut self.values).into_iter()
    }
}
impl<'a, T> IntoIterator for &'a Values<T> {
    type Item = <&'a Vec<T> as IntoIterator>::Item;
    type IntoIter = <&'a Vec<T> as IntoIterator>::IntoIter;
    fn into_iter(self) -> Self::IntoIter {
        (&self.values).into_iter()
    }
}
impl<T> IntoIterator for Values<T> {
    type Item = <Vec<T> as IntoIterator>::Item;
    type IntoIter = <Vec<T> as IntoIterator>::IntoIter;
    fn into_iter(self) -> Self::IntoIter {
        self.values.into_iter()
    }
}
#[derive(Serialize, Deserialize, Default, Clone, Debug, PartialEq)]
pub struct LogEntry {
    
    pub message: String,
    
    #[serde(default, skip_serializing_if = "Vec::is_empty")]
    pub params: Vec<Value>,
}
#[derive(Serialize, Deserialize, Default, Clone, Debug, PartialEq)]
pub struct Frame {
    
    
    
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub function: Option<String>,
    
    
    
    
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub symbol: Option<String>,
    
    
    
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub module: Option<String>,
    
    
    
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub package: Option<String>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub filename: Option<String>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub abs_path: Option<String>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub lineno: Option<u64>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub colno: Option<u64>,
    
    #[serde(default, skip_serializing_if = "Vec::is_empty")]
    pub pre_context: Vec<String>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub context_line: Option<String>,
    
    #[serde(default, skip_serializing_if = "Vec::is_empty")]
    pub post_context: Vec<String>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub in_app: Option<bool>,
    
    #[serde(default, skip_serializing_if = "Map::is_empty")]
    pub vars: Map<String, Value>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub image_addr: Option<Addr>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub instruction_addr: Option<Addr>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub symbol_addr: Option<Addr>,
}
#[derive(Serialize, Deserialize, Default, Clone, Debug, PartialEq)]
pub struct TemplateInfo {
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub filename: Option<String>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub abs_path: Option<String>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub lineno: Option<u64>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub colno: Option<u64>,
    
    #[serde(default, skip_serializing_if = "Vec::is_empty")]
    pub pre_context: Vec<String>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub context_line: Option<String>,
    
    #[serde(default, skip_serializing_if = "Vec::is_empty")]
    pub post_context: Vec<String>,
}
#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)]
pub struct Stacktrace {
    
    #[serde(default)]
    pub frames: Vec<Frame>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub frames_omitted: Option<(u64, u64)>,
    
    #[serde(default, skip_serializing_if = "Map::is_empty")]
    pub registers: Map<String, RegVal>,
}
impl Stacktrace {
    
    pub fn from_frames_reversed(mut frames: Vec<Frame>) -> Option<Stacktrace> {
        if frames.is_empty() {
            None
        } else {
            frames.reverse();
            Some(Stacktrace {
                frames,
                ..Default::default()
            })
        }
    }
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
#[serde(untagged)]
pub enum ThreadId {
    
    Int(u64),
    
    String(String),
}
impl Default for ThreadId {
    fn default() -> ThreadId {
        ThreadId::Int(0)
    }
}
impl<'a> From<&'a str> for ThreadId {
    fn from(id: &'a str) -> ThreadId {
        ThreadId::String(id.to_string())
    }
}
impl From<String> for ThreadId {
    fn from(id: String) -> ThreadId {
        ThreadId::String(id)
    }
}
impl From<i64> for ThreadId {
    fn from(id: i64) -> ThreadId {
        ThreadId::Int(id as u64)
    }
}
impl From<i32> for ThreadId {
    fn from(id: i32) -> ThreadId {
        ThreadId::Int(id as u64)
    }
}
impl From<u32> for ThreadId {
    fn from(id: u32) -> ThreadId {
        ThreadId::Int(id as u64)
    }
}
impl From<u16> for ThreadId {
    fn from(id: u16) -> ThreadId {
        ThreadId::Int(id as u64)
    }
}
impl fmt::Display for ThreadId {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            ThreadId::Int(i) => write!(f, "{}", i),
            ThreadId::String(ref s) => write!(f, "{}", s),
        }
    }
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)]
pub struct Addr(pub u64);
impl Addr {
    
    pub fn is_null(&self) -> bool {
        self.0 == 0
    }
}
impl_hex_serde!(Addr, u64);
impl From<u64> for Addr {
    fn from(addr: u64) -> Addr {
        Addr(addr)
    }
}
impl From<i32> for Addr {
    fn from(addr: i32) -> Addr {
        Addr(addr as u64)
    }
}
impl From<u32> for Addr {
    fn from(addr: u32) -> Addr {
        Addr(addr as u64)
    }
}
impl From<usize> for Addr {
    fn from(addr: usize) -> Addr {
        Addr(addr as u64)
    }
}
impl<T> From<*const T> for Addr {
    fn from(addr: *const T) -> Addr {
        Addr(addr as u64)
    }
}
impl<T> From<*mut T> for Addr {
    fn from(addr: *mut T) -> Addr {
        Addr(addr as u64)
    }
}
impl Into<u64> for Addr {
    fn into(self) -> u64 {
        self.0
    }
}
fn is_false(value: &bool) -> bool {
    !*value
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)]
pub struct RegVal(pub u64);
impl_hex_serde!(RegVal, u64);
impl From<u64> for RegVal {
    fn from(addr: u64) -> RegVal {
        RegVal(addr)
    }
}
impl From<i32> for RegVal {
    fn from(addr: i32) -> RegVal {
        RegVal(addr as u64)
    }
}
impl From<u32> for RegVal {
    fn from(addr: u32) -> RegVal {
        RegVal(addr as u64)
    }
}
impl From<usize> for RegVal {
    fn from(addr: usize) -> RegVal {
        RegVal(addr as u64)
    }
}
impl<T> From<*const T> for RegVal {
    fn from(addr: *const T) -> RegVal {
        RegVal(addr as u64)
    }
}
impl<T> From<*mut T> for RegVal {
    fn from(addr: *mut T) -> RegVal {
        RegVal(addr as u64)
    }
}
impl Into<u64> for RegVal {
    fn into(self) -> u64 {
        self.0
    }
}
#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)]
pub struct Thread {
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub id: Option<ThreadId>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub name: Option<String>,
    
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub stacktrace: Option<Stacktrace>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub raw_stacktrace: Option<Stacktrace>,
    
    #[serde(default, skip_serializing_if = "is_false")]
    pub crashed: bool,
    
    
    #[serde(default, skip_serializing_if = "is_false")]
    pub current: bool,
}
#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq)]
pub struct CError {
    
    pub number: i32,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub name: Option<String>,
}
impl From<i32> for CError {
    fn from(number: i32) -> CError {
        CError { number, name: None }
    }
}
impl Into<i32> for CError {
    fn into(self) -> i32 {
        self.number
    }
}
#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq)]
pub struct MachException {
    
    pub exception: i32,
    
    pub code: u64,
    
    pub subcode: u64,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub name: Option<String>,
}
#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq)]
pub struct PosixSignal {
    
    pub number: i32,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub code: Option<i32>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub name: Option<String>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub code_name: Option<String>,
}
impl From<i32> for PosixSignal {
    fn from(number: i32) -> PosixSignal {
        PosixSignal {
            number,
            code: None,
            name: None,
            code_name: None,
        }
    }
}
impl From<(i32, i32)> for PosixSignal {
    fn from(tuple: (i32, i32)) -> PosixSignal {
        let (number, code) = tuple;
        PosixSignal {
            number,
            code: Some(code),
            name: None,
            code_name: None,
        }
    }
}
impl Into<i32> for PosixSignal {
    fn into(self) -> i32 {
        self.number
    }
}
#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)]
pub struct MechanismMeta {
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub errno: Option<CError>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub signal: Option<PosixSignal>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub mach_exception: Option<MachException>,
}
impl MechanismMeta {
    fn is_empty(&self) -> bool {
        self.errno.is_none() && self.signal.is_none() && self.mach_exception.is_none()
    }
}
#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)]
pub struct Mechanism {
    
    #[serde(rename = "type")]
    pub ty: String,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub description: Option<String>,
    
    #[serde(default, with = "url_serde", skip_serializing_if = "Option::is_none")]
    pub help_link: Option<Url>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub handled: Option<bool>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub synthetic: Option<bool>,
    
    #[serde(default, skip_serializing_if = "Map::is_empty")]
    pub data: Map<String, Value>,
    
    #[serde(default, skip_serializing_if = "MechanismMeta::is_empty")]
    pub meta: MechanismMeta,
}
#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)]
pub struct Exception {
    
    #[serde(rename = "type")]
    pub ty: String,
    
    #[serde(skip_serializing_if = "Option::is_none")]
    pub value: Option<String>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub module: Option<String>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub stacktrace: Option<Stacktrace>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub raw_stacktrace: Option<Stacktrace>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub thread_id: Option<ThreadId>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub mechanism: Option<Mechanism>,
}
#[derive(Debug, Fail)]
#[fail(display = "invalid level")]
pub struct ParseLevelError;
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Level {
    
    Debug,
    
    Info,
    
    Warning,
    
    Error,
    
    Fatal,
}
impl Default for Level {
    fn default() -> Level {
        Level::Info
    }
}
impl str::FromStr for Level {
    type Err = ParseLevelError;
    fn from_str(string: &str) -> Result<Level, Self::Err> {
        Ok(match string {
            "debug" => Level::Debug,
            "info" | "log" => Level::Info,
            "warning" => Level::Warning,
            "error" => Level::Error,
            "fatal" => Level::Fatal,
            _ => return Err(ParseLevelError),
        })
    }
}
impl fmt::Display for Level {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Level::Debug => write!(f, "debug"),
            Level::Info => write!(f, "info"),
            Level::Warning => write!(f, "warning"),
            Level::Error => write!(f, "error"),
            Level::Fatal => write!(f, "fatal"),
        }
    }
}
impl Level {
    
    pub fn is_debug(&self) -> bool {
        *self == Level::Debug
    }
    
    pub fn is_info(&self) -> bool {
        *self == Level::Info
    }
    
    pub fn is_warning(&self) -> bool {
        *self == Level::Warning
    }
    
    pub fn is_error(&self) -> bool {
        *self == Level::Error
    }
    
    pub fn is_fatal(&self) -> bool {
        *self == Level::Fatal
    }
}
impl_str_serde!(Level);
mod breadcrumb {
    use super::*;
    pub fn default_timestamp() -> DateTime<Utc> {
        Utc::now()
    }
    pub fn default_type() -> String {
        "default".to_string()
    }
    pub fn is_default_type(ty: &str) -> bool {
        ty == "default"
    }
    pub fn default_level() -> Level {
        Level::Info
    }
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct Breadcrumb {
    
    #[serde(default = "breadcrumb::default_timestamp", with = "ts_seconds_float")]
    pub timestamp: DateTime<Utc>,
    
    #[serde(
        rename = "type",
        default = "breadcrumb::default_type",
        skip_serializing_if = "breadcrumb::is_default_type"
    )]
    pub ty: String,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub category: Option<String>,
    
    
    #[serde(
        default = "breadcrumb::default_level",
        skip_serializing_if = "Level::is_info"
    )]
    pub level: Level,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub message: Option<String>,
    
    #[serde(default, skip_serializing_if = "Map::is_empty")]
    pub data: Map<String, Value>,
}
impl Default for Breadcrumb {
    fn default() -> Breadcrumb {
        Breadcrumb {
            timestamp: breadcrumb::default_timestamp(),
            ty: breadcrumb::default_type(),
            category: Default::default(),
            level: breadcrumb::default_level(),
            message: Default::default(),
            data: Default::default(),
        }
    }
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)]
pub enum IpAddress {
    
    Auto,
    
    Exact(IpAddr),
}
impl PartialEq<IpAddr> for IpAddress {
    fn eq(&self, other: &IpAddr) -> bool {
        match *self {
            IpAddress::Auto => false,
            IpAddress::Exact(ref addr) => addr == other,
        }
    }
}
impl cmp::PartialOrd<IpAddr> for IpAddress {
    fn partial_cmp(&self, other: &IpAddr) -> Option<cmp::Ordering> {
        match *self {
            IpAddress::Auto => None,
            IpAddress::Exact(ref addr) => addr.partial_cmp(other),
        }
    }
}
impl Default for IpAddress {
    fn default() -> IpAddress {
        IpAddress::Auto
    }
}
impl fmt::Display for IpAddress {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            IpAddress::Auto => write!(f, "{{{{auto}}}}"),
            IpAddress::Exact(ref addr) => write!(f, "{}", addr),
        }
    }
}
impl From<IpAddr> for IpAddress {
    fn from(addr: IpAddr) -> IpAddress {
        IpAddress::Exact(addr)
    }
}
impl str::FromStr for IpAddress {
    type Err = AddrParseError;
    fn from_str(string: &str) -> Result<IpAddress, AddrParseError> {
        match string {
            "{{auto}}" => Ok(IpAddress::Auto),
            other => other.parse().map(IpAddress::Exact),
        }
    }
}
impl_str_serde!(IpAddress);
#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)]
pub struct User {
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub id: Option<String>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub email: Option<String>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub ip_address: Option<IpAddress>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub username: Option<String>,
    
    #[serde(flatten)]
    pub other: Map<String, Value>,
}
#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)]
pub struct Request {
    
    #[serde(default, with = "url_serde", skip_serializing_if = "Option::is_none")]
    pub url: Option<Url>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub method: Option<String>,
    
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub data: Option<String>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub query_string: Option<String>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub cookies: Option<String>,
    
    #[serde(default, skip_serializing_if = "Map::is_empty")]
    pub headers: Map<String, String>,
    
    #[serde(default, skip_serializing_if = "Map::is_empty")]
    pub env: Map<String, String>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct SystemSdkInfo {
    
    pub sdk_name: String,
    
    pub version_major: u32,
    
    pub version_minor: u32,
    
    pub version_patchlevel: u32,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(rename_all = "snake_case", tag = "type")]
pub enum DebugImage {
    
    
    Apple(AppleDebugImage),
    
    Symbolic(SymbolicDebugImage),
    
    Proguard(ProguardDebugImage),
}
impl DebugImage {
    
    pub fn type_name(&self) -> &str {
        match *self {
            DebugImage::Apple(..) => "apple",
            DebugImage::Symbolic(..) => "symbolic",
            DebugImage::Proguard(..) => "proguard",
        }
    }
}
macro_rules! into_debug_image {
    ($kind:ident, $ty:ty) => {
        impl From<$ty> for DebugImage {
            fn from(data: $ty) -> DebugImage {
                DebugImage::$kind(data)
            }
        }
    };
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct AppleDebugImage {
    
    pub name: String,
    
    pub arch: Option<String>,
    
    pub cpu_type: Option<u32>,
    
    pub cpu_subtype: Option<u32>,
    
    pub image_addr: Addr,
    
    pub image_size: u64,
    
    #[serde(default, skip_serializing_if = "Addr::is_null")]
    pub image_vmaddr: Addr,
    
    pub uuid: Uuid,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct SymbolicDebugImage {
    
    pub name: String,
    
    pub arch: Option<String>,
    
    pub image_addr: Addr,
    
    pub image_size: u64,
    
    #[serde(default, skip_serializing_if = "Addr::is_null")]
    pub image_vmaddr: Addr,
    
    pub id: DebugId,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct ProguardDebugImage {
    
    pub uuid: Uuid,
}
into_debug_image!(Apple, AppleDebugImage);
into_debug_image!(Symbolic, SymbolicDebugImage);
into_debug_image!(Proguard, ProguardDebugImage);
#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)]
pub struct DebugMeta {
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub sdk_info: Option<SystemSdkInfo>,
    
    #[serde(default, skip_serializing_if = "Vec::is_empty")]
    pub images: Vec<DebugImage>,
}
impl DebugMeta {
    
    
    
    pub fn is_empty(&self) -> bool {
        self.sdk_info.is_none() && self.images.is_empty()
    }
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct ClientSdkInfo {
    
    pub name: String,
    
    pub version: String,
    
    #[serde(default, skip_serializing_if = "Vec::is_empty")]
    pub integrations: Vec<String>,
    
    #[serde(default, skip_serializing_if = "Vec::is_empty")]
    pub packages: Vec<ClientSdkPackage>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct ClientSdkPackage {
    
    pub name: String,
    
    pub version: String,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(rename_all = "snake_case", tag = "type")]
pub enum Context {
    
    Device(Box<DeviceContext>),
    
    Os(Box<OsContext>),
    
    Runtime(Box<RuntimeContext>),
    
    App(Box<AppContext>),
    
    Browser(Box<BrowserContext>),
    
    #[serde(rename = "unknown")]
    Other(Map<String, Value>),
}
impl Context {
    
    pub fn type_name(&self) -> &str {
        match *self {
            Context::Device(..) => "device",
            Context::Os(..) => "os",
            Context::Runtime(..) => "runtime",
            Context::App(..) => "app",
            Context::Browser(..) => "browser",
            Context::Other(..) => "unknown",
        }
    }
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash)]
#[serde(rename_all = "lowercase")]
pub enum Orientation {
    
    Portrait,
    
    Landscape,
}
#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq)]
pub struct DeviceContext {
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub name: Option<String>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub family: Option<String>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub model: Option<String>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub model_id: Option<String>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub arch: Option<String>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub battery_level: Option<f32>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub orientation: Option<Orientation>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub simulator: Option<bool>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub memory_size: Option<u64>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub free_memory: Option<u64>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub usable_memory: Option<u64>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub storage_size: Option<u64>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub free_storage: Option<u64>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub external_storage_size: Option<u64>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub external_free_storage: Option<u64>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub boot_time: Option<DateTime<Utc>>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub timezone: Option<String>,
    
    #[serde(flatten)]
    pub other: Map<String, Value>,
}
#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq)]
pub struct OsContext {
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub name: Option<String>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub version: Option<String>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub build: Option<String>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub kernel_version: Option<String>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub rooted: Option<bool>,
    
    #[serde(flatten)]
    pub other: Map<String, Value>,
}
#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq)]
pub struct RuntimeContext {
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub name: Option<String>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub version: Option<String>,
    
    #[serde(flatten)]
    pub other: Map<String, Value>,
}
#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq)]
pub struct AppContext {
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub app_start_time: Option<DateTime<Utc>>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub device_app_hash: Option<String>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub build_type: Option<String>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub app_identifier: Option<String>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub app_name: Option<String>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub app_version: Option<String>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub app_build: Option<String>,
    
    #[serde(flatten)]
    pub other: Map<String, Value>,
}
#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq)]
pub struct BrowserContext {
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub name: Option<String>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub version: Option<String>,
    
    #[serde(flatten)]
    pub other: Map<String, Value>,
}
macro_rules! into_context {
    ($kind:ident, $ty:ty) => {
        impl From<$ty> for Context {
            fn from(data: $ty) -> Self {
                Context::$kind(Box::new(data))
            }
        }
    };
}
into_context!(App, AppContext);
into_context!(Device, DeviceContext);
into_context!(Os, OsContext);
into_context!(Runtime, RuntimeContext);
into_context!(Browser, BrowserContext);
mod event {
    use super::*;
    pub fn default_id() -> Uuid {
        Uuid::new_v4()
    }
    pub fn serialize_id<S: Serializer>(uuid: &Uuid, serializer: S) -> Result<S::Ok, S::Error> {
        serializer.serialize_some(&uuid.to_simple_ref().to_string())
    }
    pub fn default_level() -> Level {
        Level::Error
    }
    pub fn default_platform() -> Cow<'static, str> {
        Cow::Borrowed("other")
    }
    pub fn is_default_platform(value: &str) -> bool {
        value == "other"
    }
    static DEFAULT_FINGERPRINT: &[Cow<'static, str>] = &[Cow::Borrowed("{{ default }}")];
    pub fn default_fingerprint<'a>() -> Cow<'a, [Cow<'a, str>]> {
        Cow::Borrowed(DEFAULT_FINGERPRINT)
    }
    #[cfg_attr(feature = "cargo-clippy", allow(ptr_arg))]
    pub fn is_default_fingerprint<'a>(fp: &[Cow<'a, str>]) -> bool {
        fp.len() == 1 && ((&fp)[0] == "{{ default }}" || (&fp)[0] == "{{default}}")
    }
    pub fn default_timestamp() -> DateTime<Utc> {
        Utc::now()
    }
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct Event<'a> {
    
    #[serde(default = "event::default_id", serialize_with = "event::serialize_id")]
    pub event_id: Uuid,
    
    #[serde(
        default = "event::default_level",
        skip_serializing_if = "Level::is_error"
    )]
    pub level: Level,
    
    #[serde(
        default = "event::default_fingerprint",
        skip_serializing_if = "event::is_default_fingerprint"
    )]
    pub fingerprint: Cow<'a, [Cow<'a, str>]>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub culprit: Option<String>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub transaction: Option<String>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub message: Option<String>,
    
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub logentry: Option<LogEntry>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub logger: Option<String>,
    
    #[serde(default, skip_serializing_if = "Map::is_empty")]
    pub modules: Map<String, String>,
    
    #[serde(
        default = "event::default_platform",
        skip_serializing_if = "event::is_default_platform"
    )]
    pub platform: Cow<'a, str>,
    
    
    
    #[serde(default = "event::default_timestamp", with = "ts_seconds_float")]
    pub timestamp: DateTime<Utc>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub server_name: Option<Cow<'a, str>>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub release: Option<Cow<'a, str>>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub dist: Option<Cow<'a, str>>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub environment: Option<Cow<'a, str>>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub user: Option<User>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub request: Option<Request>,
    
    #[serde(default, skip_serializing_if = "Map::is_empty")]
    pub contexts: Map<String, Context>,
    
    #[serde(default, skip_serializing_if = "Values::is_empty")]
    pub breadcrumbs: Values<Breadcrumb>,
    
    #[serde(default, skip_serializing_if = "Values::is_empty")]
    pub exception: Values<Exception>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub stacktrace: Option<Stacktrace>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub template: Option<TemplateInfo>,
    
    #[serde(default, skip_serializing_if = "Values::is_empty")]
    pub threads: Values<Thread>,
    
    #[serde(default, skip_serializing_if = "Map::is_empty")]
    pub tags: Map<String, String>,
    
    #[serde(default, skip_serializing_if = "Map::is_empty")]
    pub extra: Map<String, Value>,
    
    #[serde(default, skip_serializing_if = "DebugMeta::is_empty")]
    pub debug_meta: Cow<'a, DebugMeta>,
    
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub sdk: Option<Cow<'a, ClientSdkInfo>>,
}
impl<'a> Default for Event<'a> {
    fn default() -> Self {
        Event {
            event_id: event::default_id(),
            level: event::default_level(),
            fingerprint: event::default_fingerprint(),
            culprit: Default::default(),
            transaction: Default::default(),
            message: Default::default(),
            logentry: Default::default(),
            logger: Default::default(),
            modules: Default::default(),
            platform: event::default_platform(),
            timestamp: event::default_timestamp(),
            server_name: Default::default(),
            release: Default::default(),
            dist: Default::default(),
            environment: Default::default(),
            user: Default::default(),
            request: Default::default(),
            contexts: Default::default(),
            breadcrumbs: Default::default(),
            exception: Default::default(),
            stacktrace: Default::default(),
            template: Default::default(),
            threads: Default::default(),
            tags: Default::default(),
            extra: Default::default(),
            debug_meta: Default::default(),
            sdk: Default::default(),
        }
    }
}
impl<'a> Event<'a> {
    
    pub fn new() -> Event<'a> {
        Default::default()
    }
    
    pub fn into_owned(self) -> Event<'static> {
        Event {
            event_id: self.event_id,
            level: self.level,
            fingerprint: Cow::Owned(
                self.fingerprint
                    .iter()
                    .map(|x| Cow::Owned(x.to_string()))
                    .collect(),
            ),
            culprit: self.culprit,
            transaction: self.transaction,
            message: self.message,
            logentry: self.logentry,
            logger: self.logger,
            modules: self.modules,
            platform: Cow::Owned(self.platform.into_owned()),
            timestamp: self.timestamp,
            server_name: self.server_name.map(|x| Cow::Owned(x.into_owned())),
            release: self.release.map(|x| Cow::Owned(x.into_owned())),
            dist: self.dist.map(|x| Cow::Owned(x.into_owned())),
            environment: self.environment.map(|x| Cow::Owned(x.into_owned())),
            user: self.user,
            request: self.request,
            contexts: self.contexts,
            breadcrumbs: self.breadcrumbs,
            exception: self.exception,
            stacktrace: self.stacktrace,
            template: self.template,
            threads: self.threads,
            tags: self.tags,
            extra: self.extra,
            debug_meta: Cow::Owned(self.debug_meta.into_owned()),
            sdk: self.sdk.map(|x| Cow::Owned(x.into_owned())),
        }
    }
}
impl<'a> fmt::Display for Event<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Event(id: {}, ts: {})", self.event_id, self.timestamp)
    }
}