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