Skip to main content

surfer_translation_types/
result.rs

1#[cfg(feature = "wasm_plugins")]
2use extism_convert::{FromBytes, Json, ToBytes};
3use serde::{Deserialize, Serialize};
4
5use crate::ValueKind;
6
7#[cfg_attr(feature = "wasm_plugins", derive(FromBytes, ToBytes))]
8#[cfg_attr(feature = "wasm_plugins", encoding(Json))]
9#[derive(Clone, Serialize, Deserialize)]
10pub struct TranslationResult {
11    pub val: ValueRepr,
12    pub subfields: Vec<SubFieldTranslationResult>,
13    pub kind: ValueKind,
14}
15
16impl TranslationResult {
17    pub fn single_string(s: impl Into<String>, kind: ValueKind) -> Self {
18        TranslationResult {
19            val: ValueRepr::String(s.into()),
20            subfields: vec![],
21            kind,
22        }
23    }
24}
25
26/// The representation of the value, compound values can be
27/// be represented by the repr of their subfields
28#[derive(Clone, Serialize, Deserialize)]
29pub enum ValueRepr {
30    Bit(char),
31    /// The value is `.0` raw bits, and can be translated by further translators
32    Bits(u32, String),
33    /// The value is exactly the specified string
34    String(String),
35    /// Represent the value as (f1, f2, f3...)
36    Tuple,
37    /// Represent the value as {f1: v1, f2: v2, f3: v3...}
38    Struct,
39    /// Represent as a spade-like enum with the specified field being shown.
40    /// The index is the index of the option which is currently selected, the name is
41    /// the name of that option to avoid having to look that up
42    Enum {
43        idx: usize,
44        name: String,
45    },
46    /// Represent the value as [f1, f2, f3...]
47    Array,
48    /// The variable value is not present. This is used to draw variables which are
49    /// validated by other variables.
50    NotPresent,
51    Event,
52}
53
54#[derive(Clone, Serialize, Deserialize)]
55pub struct SubFieldFlatTranslationResult {
56    pub names: Vec<String>,
57    pub value: Option<TranslatedValue>,
58}
59
60// A tree of format results for a variable, to be flattened into `SubFieldFlatTranslationResult`s
61pub struct HierFormatResult {
62    pub names: Vec<String>,
63    pub this: Option<TranslatedValue>,
64    /// A list of subfields of arbitrary depth, flattened to remove hierarchy.
65    /// i.e. `{a: {b: 0}, c: 0}` is flattened to `vec![a: {b: 0}, [a, b]: 0, c: 0]`
66    pub fields: Vec<HierFormatResult>,
67}
68
69impl HierFormatResult {
70    pub fn collect_into(self, into: &mut Vec<SubFieldFlatTranslationResult>) {
71        into.push(SubFieldFlatTranslationResult {
72            names: self.names,
73            value: self.this,
74        });
75        self.fields.into_iter().for_each(|r| r.collect_into(into));
76    }
77}
78
79#[derive(Clone, Serialize, Deserialize)]
80pub struct SubFieldTranslationResult {
81    pub name: String,
82    pub result: TranslationResult,
83}
84
85impl SubFieldTranslationResult {
86    pub fn new(name: &impl ToString, result: TranslationResult) -> Self {
87        SubFieldTranslationResult {
88            name: name.to_string(),
89            result,
90        }
91    }
92}
93
94#[derive(Clone, PartialEq, Serialize, Deserialize)]
95pub struct TranslatedValue {
96    pub value: String,
97    pub kind: ValueKind,
98}
99
100impl TranslatedValue {
101    #[must_use]
102    pub fn from_basic_translate(result: (String, ValueKind)) -> Self {
103        TranslatedValue {
104            value: result.0,
105            kind: result.1,
106        }
107    }
108
109    pub fn new(value: &impl ToString, kind: ValueKind) -> Self {
110        TranslatedValue {
111            value: value.to_string(),
112            kind,
113        }
114    }
115}