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 Display for PsValue {
48 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
49 let val: InternalVal = self.clone().into();
50 write!(f, "{}", val)
51 }
52}
53
54impl From<PsValue> for InternalVal {
55 fn from(val: PsValue) -> Self {
56 match val {
57 PsValue::Null => InternalVal::Null,
58 PsValue::Bool(b) => InternalVal::Bool(b),
59 PsValue::Int(i) => InternalVal::Int(i),
60 PsValue::Float(f) => InternalVal::Float(f),
61 PsValue::Char(c) => InternalVal::Char(c),
62 PsValue::String(s) => InternalVal::String(PsString(s)),
63 PsValue::Array(arr) => {
64 InternalVal::Array(arr.iter().map(|v| v.clone().into()).collect())
65 }
66 PsValue::HashTable(hash) => InternalVal::HashTable(
67 hash.iter()
68 .map(|(k, v)| (k.clone(), v.clone().into()))
69 .collect(),
70 ),
71 }
72 }
73}
74
75impl From<InternalVal> for PsValue {
76 fn from(val: InternalVal) -> Self {
77 match val {
78 InternalVal::Null => PsValue::Null,
79 InternalVal::Bool(b) => PsValue::Bool(b),
80 InternalVal::Int(i) => PsValue::Int(i),
81 InternalVal::Float(f) => PsValue::Float(f),
82 InternalVal::Char(c) => PsValue::Char(c),
83 InternalVal::String(PsString(s)) => PsValue::String(s),
84 InternalVal::Array(arr) => {
85 PsValue::Array(arr.iter().map(|v| v.clone().into()).collect())
86 }
87 InternalVal::HashTable(hash) => PsValue::HashTable(
88 hash.iter()
89 .map(|(k, v)| (k.clone(), v.clone().into()))
90 .collect(),
91 ),
92 InternalVal::RuntimeObject(obj) => PsValue::String(obj.name()),
93 InternalVal::ScriptBlock(sb) => PsValue::String(sb.raw_text),
94 InternalVal::ScriptText(st) => PsValue::String(st.clone()),
95 InternalVal::NonDisplayed(box_val) => (*box_val).into(),
96 }
97 }
98}
99
100#[derive(Debug)]
101pub struct ScriptResult {
102 result: PsValue,
103 stream: Vec<String>,
104 evaluated_statements: Vec<String>,
105 tokens: Tokens,
106 errors: Vec<ParserError>,
107 script_values: HashMap<String, PsValue>,
108}
109
110impl ScriptResult {
111 pub(crate) fn new(
112 result: InternalVal,
113 stream: Vec<StreamMessage>,
114 evaluated_statements: Vec<String>,
115 tokens: Tokens,
116 errors: Vec<ParserError>,
117 script_values: HashMap<String, PsValue>,
118 ) -> Self {
119 Self {
120 result: result.into(),
121 stream: stream
122 .iter()
123 .map(|msg| msg.to_string())
124 .collect::<Vec<String>>(),
125 evaluated_statements,
126 tokens,
127 errors,
128 script_values,
129 }
130 }
131
132 pub fn result(&self) -> PsValue {
133 self.result.clone()
134 }
135
136 pub fn deobfuscated_lines(&self) -> Vec<String> {
137 self.evaluated_statements.clone()
138 }
139
140 pub fn deobfuscated(&self) -> String {
141 self.evaluated_statements.join(NEWLINE)
142 }
143
144 pub fn tokens(&self) -> Tokens {
145 self.tokens.clone()
146 }
147
148 pub fn errors(&self) -> Vec<ParserError> {
149 self.errors.clone()
150 }
151
152 pub fn output(&self) -> String {
153 self.stream.join(NEWLINE)
154 }
155
156 pub fn output_lines(&self) -> Vec<String> {
157 self.stream.clone()
158 }
159
160 pub fn script_variables(&self) -> HashMap<String, PsValue> {
161 self.script_values.clone()
162 }
163}