use std::cmp::Ord;
use std::ops;
use std::path::PathBuf;
use crate::base64;
use num_derive::FromPrimitive;
use serde::{Deserialize, Serialize};
use serde_repr::*;
use schemars::JsonSchema;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum TraceLowLevelEvent {
Step(StepRecord),
Path(PathBuf), VariableName(String), Variable(String), Type(TypeRecord), Value(FullValueRecord), Function(FunctionRecord), Call(CallRecord),
Return(ReturnRecord),
Event(RecordEvent),
Asm(Vec<String>),
BindVariable(BindVariableRecord), Assignment(AssignmentRecord), DropVariables(Vec<VariableId>),
CompoundValue(CompoundValueRecord),
CellValue(CellValueRecord),
AssignCompoundItem(AssignCompoundItemRecord),
AssignCell(AssignCellRecord),
VariableCell(VariableCellRecord),
DropVariable(VariableId),
ThreadStart(ThreadId),
ThreadExit(ThreadId),
ThreadSwitch(ThreadId),
DropLastStep,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BindVariableRecord {
pub variable_id: VariableId,
pub place: Place,
}
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
pub enum PassBy {
#[default]
Value,
Reference,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AssignmentRecord {
pub to: VariableId,
pub pass_by: PassBy,
pub from: RValue,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "kind")]
pub enum RValue {
Simple(VariableId),
Compound(Vec<VariableId>),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CompoundValueRecord {
pub place: Place,
pub value: ValueRecord,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CellValueRecord {
pub place: Place,
pub value: ValueRecord,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub struct AssignCompoundItemRecord {
pub place: Place,
pub index: usize,
pub item_place: Place,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AssignCellRecord {
pub place: Place,
pub new_value: ValueRecord,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VariableCellRecord {
pub variable_id: VariableId,
pub place: Place,
}
#[derive(Hash, Debug, Default, Copy, Clone, Serialize, Deserialize, Ord, PartialOrd, Eq, PartialEq)]
pub struct Place(pub i64);
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FullValueRecord {
pub variable_id: VariableId,
pub value: ValueRecord,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TraceMetadata {
pub workdir: PathBuf,
pub program: String,
pub args: Vec<String>,
}
#[derive(Debug, Default, Copy, Clone, PartialEq, Serialize, Deserialize)]
#[serde(transparent)]
pub struct CallKey(pub i64);
impl Into<usize> for CallKey {
fn into(self) -> usize {
self.0 as usize
}
}
impl ops::Add<usize> for CallKey {
type Output = CallKey;
fn add(self, arg: usize) -> Self::Output {
CallKey(self.0 + arg as i64)
}
}
impl ops::AddAssign<usize> for CallKey {
fn add_assign(&mut self, arg: usize) {
self.0 += arg as i64;
}
}
pub const NO_KEY: CallKey = CallKey(-1);
#[derive(Debug, Default, Copy, Clone, Serialize, Deserialize, PartialEq)]
#[serde(transparent)]
pub struct Line(pub i64);
impl Into<usize> for Line {
fn into(self) -> usize {
self.0 as usize
}
}
impl Into<i64> for Line {
fn into(self) -> i64 {
self.0
}
}
#[derive(Hash, Debug, Default, Copy, Clone, Serialize, Deserialize, Ord, PartialOrd, Eq, PartialEq)]
#[serde(transparent)]
pub struct PathId(pub usize);
impl Into<usize> for PathId {
fn into(self) -> usize {
self.0
}
}
#[derive(Debug, Default, Copy, Clone, Serialize, Deserialize, Ord, PartialOrd, Eq, PartialEq)]
#[serde(transparent)]
pub struct StepId(pub i64);
impl Into<usize> for StepId {
fn into(self) -> usize {
self.0 as usize
}
}
impl ops::Add<usize> for StepId {
type Output = StepId;
fn add(self, arg: usize) -> Self::Output {
StepId(self.0 + arg as i64)
}
}
impl ops::Sub<usize> for StepId {
type Output = StepId;
fn sub(self, arg: usize) -> Self::Output {
StepId(self.0 - arg as i64)
}
}
#[derive(Hash, Debug, Default, Copy, Clone, Serialize, Deserialize, Ord, PartialOrd, Eq, PartialEq)]
pub struct VariableId(pub usize);
impl Into<usize> for VariableId {
fn into(self) -> usize {
self.0
}
}
#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq)]
pub struct FunctionId(pub usize);
impl Into<usize> for FunctionId {
fn into(self) -> usize {
self.0
}
}
#[derive(Hash, Debug, Default, Copy, Clone, Serialize, Deserialize, Ord, PartialOrd, Eq, PartialEq)]
pub struct ThreadId(pub u64);
impl Into<u64> for ThreadId {
fn into(self) -> u64 {
self.0
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CallRecord {
pub function_id: FunctionId,
pub args: Vec<FullValueRecord>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ReturnRecord {
pub return_value: ValueRecord,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FunctionRecord {
pub path_id: PathId,
pub line: Line,
pub name: String,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
pub struct StepRecord {
pub path_id: PathId,
pub line: Line,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VariableRecord {
pub name: String,
pub value: ValueRecord,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TypeRecord {
pub kind: TypeKind,
pub lang_type: String,
pub specific_info: TypeSpecificInfo,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FieldTypeRecord {
pub name: String,
pub type_id: TypeId,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "kind")]
pub enum TypeSpecificInfo {
None,
Struct { fields: Vec<FieldTypeRecord> },
Pointer { dereference_type_id: TypeId },
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RecordEvent {
pub kind: EventLogKind,
pub metadata: String,
pub content: String,
}
#[derive(Debug, Default, Copy, Clone, Serialize, Deserialize, PartialEq)]
#[serde(transparent)]
pub struct TypeId(pub usize);
impl Into<usize> for TypeId {
fn into(self) -> usize {
self.0
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(tag = "kind")]
pub enum ValueRecord {
Int {
i: i64,
type_id: TypeId,
},
Float {
f: f64,
type_id: TypeId,
},
Bool {
b: bool,
type_id: TypeId,
},
String {
text: String,
type_id: TypeId,
},
Sequence {
elements: Vec<ValueRecord>,
is_slice: bool,
type_id: TypeId,
},
Tuple {
elements: Vec<ValueRecord>,
type_id: TypeId,
},
Struct {
field_values: Vec<ValueRecord>,
type_id: TypeId, },
Variant {
discriminator: String, contents: Box<ValueRecord>, type_id: TypeId,
},
Reference {
dereferenced: Box<ValueRecord>,
address: u64,
mutable: bool,
type_id: TypeId,
},
Raw {
r: String,
type_id: TypeId,
},
Error {
msg: String,
type_id: TypeId,
},
None {
type_id: TypeId,
},
Cell {
place: Place,
},
BigInt {
#[serde(with = "base64")]
b: Vec<u8>, negative: bool,
type_id: TypeId,
},
}
#[derive(Debug, Default, Copy, Clone, FromPrimitive, Serialize_repr, Deserialize_repr, PartialEq, JsonSchema)]
#[repr(u8)]
pub enum TypeKind {
#[default]
Seq,
Set,
HashSet,
OrderedSet,
Array,
Varargs,
Struct,
Int,
Float,
String,
CString,
Char,
Bool,
Literal,
Ref,
Recursion,
Raw,
Enum,
Enum16,
Enum32,
C,
TableKind,
Union,
Pointer,
Error,
FunctionKind,
TypeValue,
Tuple,
Variant,
Html,
None,
NonExpanded,
Any,
Slice,
}
#[derive(Debug, Default, Copy, Clone, FromPrimitive, Serialize_repr, Deserialize_repr, PartialEq, JsonSchema)]
#[repr(u8)]
pub enum EventLogKind {
#[default]
Write,
WriteFile,
WriteOther,
Read,
ReadFile,
ReadOther,
ReadDir,
OpenDir,
CloseDir,
Socket,
Open,
Error,
TraceLogEvent,
EvmEvent,
}