ps_parser/parser/
script_result.rs

1use 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}