ps_parser/parser/
script_result.rs1use std::{collections::HashMap, fmt::Display};
2
3use super::{ParserError, Tokens, Val as InternalVal};
4use crate::{
5 NEWLINE,
6 parser::{StreamMessage, value::PsString},
7};
8
9#[derive(Debug, Clone, PartialEq)]
10pub enum PsValue {
11 Null,
12 Bool(bool),
13 Int(i64),
14 Float(f64),
15 Char(u32),
16 String(String),
17 Array(Vec<PsValue>),
18 HashTable(HashMap<String, PsValue>),
19}
20
21impl core::fmt::Display for PsString {
22 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
23 write!(f, "{}", self.0)
24 }
25}
26
27impl PsValue {
28 pub fn is_true(&self) -> bool {
29 match self {
30 PsValue::Bool(b) => *b,
31 PsValue::Int(i) => *i != 0,
32 PsValue::Float(f) => *f != 0.0,
33 PsValue::Char(c) => *c != 0,
34 PsValue::String(s) => !s.is_empty(),
35 PsValue::Array(arr) => !arr.is_empty(),
36 PsValue::HashTable(hash) => !hash.is_empty(),
37 PsValue::Null => false,
38 }
39 }
40}
41impl From<char> for PsValue {
42 fn from(c: char) -> Self {
43 PsValue::Char(c as u32)
44 }
45}
46
47impl From<String> for PsValue {
48 fn from(s: String) -> Self {
49 PsValue::String(s)
50 }
51}
52
53impl Display for PsValue {
54 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
55 let val: InternalVal = self.clone().into();
56 write!(f, "{}", val)
57 }
58}
59
60impl From<PsValue> for InternalVal {
61 fn from(val: PsValue) -> Self {
62 match val {
63 PsValue::Null => InternalVal::Null,
64 PsValue::Bool(b) => InternalVal::Bool(b),
65 PsValue::Int(i) => InternalVal::Int(i),
66 PsValue::Float(f) => InternalVal::Float(f),
67 PsValue::Char(c) => InternalVal::Char(c),
68 PsValue::String(s) => InternalVal::String(PsString(s)),
69 PsValue::Array(arr) => {
70 InternalVal::Array(arr.iter().map(|v| v.clone().into()).collect())
71 }
72 PsValue::HashTable(hash) => InternalVal::HashTable(
73 hash.iter()
74 .map(|(k, v)| (k.clone(), v.clone().into()))
75 .collect(),
76 ),
77 }
78 }
79}
80
81impl From<InternalVal> for PsValue {
82 fn from(val: InternalVal) -> Self {
83 match val {
84 InternalVal::Null => PsValue::Null,
85 InternalVal::Bool(b) => PsValue::Bool(b),
86 InternalVal::Int(i) => PsValue::Int(i),
87 InternalVal::Float(f) => PsValue::Float(f),
88 InternalVal::Char(c) => PsValue::Char(c),
89 InternalVal::String(PsString(s)) => PsValue::String(s),
90 InternalVal::Array(arr) => {
91 PsValue::Array(arr.iter().map(|v| v.clone().into()).collect())
92 }
93 InternalVal::HashTable(hash) => PsValue::HashTable(
94 hash.iter()
95 .map(|(k, v)| (k.clone(), v.clone().into()))
96 .collect(),
97 ),
98 InternalVal::RuntimeObject(obj) => PsValue::String(obj.to_string()),
99 InternalVal::RuntimeType(obj) => PsValue::String(obj.describe()),
100 InternalVal::ScriptBlock(sb) => PsValue::String(sb.raw_text),
101 InternalVal::ScriptText(st) => PsValue::String(st.clone()),
102 InternalVal::NonDisplayed(box_val) => (*box_val).into(),
103 }
104 }
105}
106
107#[derive(Debug)]
108pub struct ScriptResult {
109 result: PsValue,
110 stream: Vec<String>,
111 evaluated_statements: Vec<String>,
112 tokens: Tokens,
113 errors: Vec<ParserError>,
114 script_values: HashMap<String, PsValue>,
115}
116
117impl ScriptResult {
118 pub(crate) fn new(
119 result: InternalVal,
120 stream: Vec<StreamMessage>,
121 evaluated_statements: Vec<String>,
122 tokens: Tokens,
123 errors: Vec<ParserError>,
124 script_values: HashMap<String, PsValue>,
125 ) -> Self {
126 Self {
127 result: result.into(),
128 stream: stream
129 .iter()
130 .map(|msg| msg.to_string())
131 .collect::<Vec<String>>(),
132 evaluated_statements,
133 tokens,
134 errors,
135 script_values,
136 }
137 }
138
139 pub fn result(&self) -> PsValue {
140 self.result.clone()
141 }
142
143 pub fn deobfuscated_lines(&self) -> Vec<String> {
144 self.evaluated_statements.clone()
145 }
146
147 pub fn deobfuscated(&self) -> String {
148 self.evaluated_statements.join(NEWLINE)
149 }
150
151 pub fn tokens(&self) -> Tokens {
152 self.tokens.clone()
153 }
154
155 pub fn errors(&self) -> Vec<ParserError> {
156 self.errors.clone()
157 }
158
159 pub fn output(&self) -> String {
160 self.stream.join(NEWLINE)
161 }
162
163 pub fn output_lines(&self) -> Vec<String> {
164 self.stream.clone()
165 }
166
167 pub fn script_variables(&self) -> HashMap<String, PsValue> {
168 self.script_values.clone()
169 }
170}