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.
49    ///
50    /// This is used to draw variables which are validated by other variables.
51    NotPresent,
52    Event,
53}
54
55#[derive(Clone, Serialize, Deserialize)]
56pub struct SubFieldFlatTranslationResult {
57    pub names: Vec<String>,
58    pub value: Option<TranslatedValue>,
59}
60
61// A tree of format results for a variable, to be flattened into `SubFieldFlatTranslationResult`s
62pub struct HierFormatResult {
63    pub names: Vec<String>,
64    pub this: Option<TranslatedValue>,
65    /// A list of subfields of arbitrary depth, flattened to remove hierarchy.
66    /// i.e. `{a: {b: 0}, c: 0}` is flattened to `vec![a: {b: 0}, [a, b]: 0, c: 0]`
67    pub fields: Vec<HierFormatResult>,
68}
69
70impl HierFormatResult {
71    pub fn collect_into(self, into: &mut Vec<SubFieldFlatTranslationResult>) {
72        into.push(SubFieldFlatTranslationResult {
73            names: self.names,
74            value: self.this,
75        });
76        self.fields.into_iter().for_each(|r| r.collect_into(into));
77    }
78}
79
80#[derive(Clone, Serialize, Deserialize)]
81pub struct SubFieldTranslationResult {
82    pub name: String,
83    pub result: TranslationResult,
84}
85
86impl SubFieldTranslationResult {
87    pub fn new(name: &impl ToString, result: TranslationResult) -> Self {
88        SubFieldTranslationResult {
89            name: name.to_string(),
90            result,
91        }
92    }
93}
94
95#[derive(Clone, PartialEq, Serialize, Deserialize)]
96pub struct TranslatedValue {
97    pub value: String,
98    pub kind: ValueKind,
99}
100
101impl TranslatedValue {
102    #[must_use]
103    pub fn from_basic_translate(result: (String, ValueKind)) -> Self {
104        TranslatedValue {
105            value: result.0,
106            kind: result.1,
107        }
108    }
109
110    pub fn new(value: &impl ToString, kind: ValueKind) -> Self {
111        TranslatedValue {
112            value: value.to_string(),
113            kind,
114        }
115    }
116}