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 PsValue {
22 pub fn is_true(&self) -> bool {
23 match self {
24 PsValue::Bool(b) => *b,
25 PsValue::Int(i) => *i != 0,
26 PsValue::Float(f) => *f != 0.0,
27 PsValue::Char(c) => *c != 0,
28 PsValue::String(s) => !s.is_empty(),
29 PsValue::Array(arr) => !arr.is_empty(),
30 PsValue::HashTable(hash) => !hash.is_empty(),
31 PsValue::Null => false,
32 }
33 }
34}
35impl From<char> for PsValue {
36 fn from(c: char) -> Self {
37 PsValue::Char(c as u32)
38 }
39}
40
41impl Display for PsValue {
42 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
43 let val: InternalVal = self.clone().into();
44 write!(f, "{}", val)
45 }
46}
47
48impl From<PsValue> for InternalVal {
49 fn from(val: PsValue) -> Self {
50 match val {
51 PsValue::Null => InternalVal::Null,
52 PsValue::Bool(b) => InternalVal::Bool(b),
53 PsValue::Int(i) => InternalVal::Int(i),
54 PsValue::Float(f) => InternalVal::Float(f),
55 PsValue::Char(c) => InternalVal::Char(c),
56 PsValue::String(s) => InternalVal::String(PsString(s)),
57 PsValue::Array(arr) => {
58 InternalVal::Array(arr.iter().map(|v| v.clone().into()).collect())
59 }
60 PsValue::HashTable(hash) => InternalVal::HashTable(
61 hash.iter()
62 .map(|(k, v)| (k.clone(), v.clone().into()))
63 .collect(),
64 ),
65 }
66 }
67}
68
69impl From<InternalVal> for PsValue {
70 fn from(val: InternalVal) -> Self {
71 match val {
72 InternalVal::Null => PsValue::Null,
73 InternalVal::Bool(b) => PsValue::Bool(b),
74 InternalVal::Int(i) => PsValue::Int(i),
75 InternalVal::Float(f) => PsValue::Float(f),
76 InternalVal::Char(c) => PsValue::Char(c),
77 InternalVal::String(PsString(s)) => PsValue::String(s),
78 InternalVal::Array(arr) => {
79 PsValue::Array(arr.iter().map(|v| v.clone().into()).collect())
80 }
81 InternalVal::HashTable(hash) => PsValue::HashTable(
82 hash.iter()
83 .map(|(k, v)| (k.clone(), v.clone().into()))
84 .collect(),
85 ),
86 InternalVal::RuntimeObject(obj) => PsValue::String(obj.name()),
87 InternalVal::ScriptBlock(obj) => PsValue::String(obj.0.clone()),
88 InternalVal::ScriptText(st) => PsValue::String(st.clone()),
89 }
90 }
91}
92
93#[derive(Debug)]
94pub struct ScriptResult {
95 result: PsValue,
96 stream: Vec<String>,
97 evaluated_statements: Vec<String>,
98 tokens: Tokens,
99 errors: Vec<ParserError>,
100}
101
102impl ScriptResult {
103 pub(crate) fn new(
104 result: InternalVal,
105 stream: Vec<StreamMessage>,
106 evaluated_statements: Vec<String>,
107 tokens: Tokens,
108 errors: Vec<ParserError>,
109 ) -> Self {
110 Self {
111 result: result.into(),
112 stream: stream
113 .iter()
114 .cloned()
115 .map(|msg| msg.to_string())
116 .collect::<Vec<String>>(),
117 evaluated_statements,
118 tokens,
119 errors,
120 }
121 }
122
123 pub fn result(&self) -> PsValue {
124 self.result.clone()
125 }
126
127 pub fn deobfuscated_lines(&self) -> Vec<String> {
128 self.evaluated_statements.clone()
129 }
130
131 pub fn deobfuscated(&self) -> String {
132 self.evaluated_statements.join(NEWLINE)
133 }
134
135 pub fn tokens(&self) -> Tokens {
136 self.tokens.clone()
137 }
138
139 pub fn errors(&self) -> Vec<ParserError> {
140 self.errors.clone()
141 }
142
143 pub fn output(&self) -> String {
144 self.stream.join(NEWLINE)
145 }
146
147 pub fn output_lines(&self) -> Vec<String> {
148 self.stream.clone()
149 }
150}