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