selene_lib/standard_library/
v1.rs

1// An intentionally separate implementation of the standard library as it existed
2// before version 2.
3// This is so that any changes to the v2 standard library don't affect the old one.
4use std::{
5    collections::{BTreeMap, HashMap},
6    fmt,
7};
8
9use serde::{
10    de::{self, Deserializer, Visitor},
11    ser::{SerializeMap, SerializeSeq, Serializer},
12    Deserialize, Serialize,
13};
14
15lazy_static::lazy_static! {
16    static ref ANY_TABLE: BTreeMap<String, Field> = {
17        let mut map = BTreeMap::new();
18        map.insert("*".to_owned(), Field::Any);
19        map
20    };
21}
22
23#[derive(Clone, Debug, Default, PartialEq, Eq, Deserialize, Serialize)]
24pub struct StandardLibrary {
25    #[serde(rename = "selene")]
26    pub meta: Option<StandardLibraryMeta>,
27    #[serde(flatten)]
28    pub globals: BTreeMap<String, Field>,
29    #[serde(skip)]
30    pub structs: BTreeMap<String, Field>,
31}
32
33#[derive(Clone, Debug, Default, PartialEq, Eq, Deserialize, Serialize)]
34pub struct StandardLibraryMeta {
35    #[serde(default)]
36    pub base: Option<String>,
37    #[serde(default)]
38    pub name: Option<String>,
39    #[serde(default)]
40    pub structs: Option<BTreeMap<String, BTreeMap<String, Field>>>,
41}
42
43#[derive(Clone, Debug, PartialEq, Eq)]
44pub struct FunctionBehavior {
45    pub arguments: Vec<Argument>,
46    pub method: bool,
47}
48
49#[derive(Clone, Debug, PartialEq, Eq)]
50pub enum Field {
51    Any,
52    Complex {
53        function: Option<FunctionBehavior>,
54        table: BTreeMap<String, Field>,
55    },
56    Property {
57        writable: Option<Writable>,
58    },
59    Struct(String),
60    Removed,
61}
62
63impl From<BTreeMap<String, Field>> for Field {
64    fn from(table: BTreeMap<String, Field>) -> Self {
65        Field::Complex {
66            function: None,
67            table,
68        }
69    }
70}
71
72impl From<FunctionBehavior> for Field {
73    fn from(function: FunctionBehavior) -> Self {
74        Field::Complex {
75            function: Some(function),
76            table: BTreeMap::new(),
77        }
78    }
79}
80
81impl<'de> Deserialize<'de> for Field {
82    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
83        let field_raw = FieldSerde::deserialize(deserializer)?;
84
85        if field_raw.any {
86            return Ok(Field::Any);
87        }
88
89        if field_raw.removed {
90            return Ok(Field::Removed);
91        }
92
93        let is_function = field_raw.args.is_some() || field_raw.method;
94
95        if !field_raw.property
96            && !is_function
97            && field_raw.children.is_empty()
98            && field_raw.strukt.is_none()
99        {
100            return Err(de::Error::custom(
101                "can't determine what kind of field this is",
102            ));
103        }
104
105        if field_raw.property && is_function {
106            return Err(de::Error::custom("field is both a property and a function"));
107        }
108
109        if field_raw.property {
110            return Ok(Field::Property {
111                writable: field_raw.writable,
112            });
113        }
114
115        if let Some(name) = field_raw.strukt {
116            return Ok(Field::Struct(name));
117        }
118
119        let function_behavior = if is_function {
120            Some(FunctionBehavior {
121                arguments: field_raw.args.unwrap_or_default(),
122                method: field_raw.method,
123            })
124        } else {
125            None
126        };
127
128        Ok(Field::Complex {
129            function: function_behavior,
130            table: field_raw.children,
131        })
132    }
133}
134
135impl Serialize for Field {
136    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
137        match self {
138            Field::Any => {
139                let mut map = serializer.serialize_map(Some(1))?;
140                map.serialize_entry("any", &true)?;
141                map.end()
142            }
143
144            Field::Complex { function, table } => {
145                let mut map = serializer.serialize_map(None)?;
146
147                if let Some(function) = function {
148                    if function.method {
149                        map.serialize_entry("method", &true)?;
150                    }
151                    map.serialize_entry("args", &function.arguments)?;
152                }
153
154                for (key, value) in table.iter() {
155                    map.serialize_entry(key, value)?;
156                }
157
158                map.end()
159            }
160
161            Field::Property { writable } => {
162                let mut map = serializer.serialize_map(None)?;
163                map.serialize_entry("property", &true)?;
164                if let Some(writable) = writable {
165                    map.serialize_entry("writable", writable)?;
166                }
167                map.end()
168            }
169
170            Field::Struct(name) => {
171                let mut map = serializer.serialize_map(Some(1))?;
172                map.serialize_entry("struct", name)?;
173                map.end()
174            }
175
176            Field::Removed => {
177                let mut map = serializer.serialize_map(Some(1))?;
178                map.serialize_entry("removed", &true)?;
179                map.end()
180            }
181        }
182    }
183}
184
185#[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize, Serialize)]
186#[serde(rename_all = "kebab-case")]
187pub enum Writable {
188    // New fields can be added and set, but variable itself cannot be redefined
189    NewFields,
190    // New fields can't be added, but entire variable can be overridden
191    Overridden,
192    // New fields can be added and entire variable can be overridden
193    Full,
194}
195
196#[derive(Debug, Deserialize)]
197struct FieldSerde {
198    #[serde(default)]
199    property: bool,
200    #[serde(default)]
201    method: bool,
202    #[serde(default)]
203    removed: bool,
204    #[serde(default)]
205    writable: Option<Writable>,
206    #[serde(default)]
207    args: Option<Vec<Argument>>,
208    #[serde(default)]
209    #[serde(rename = "struct")]
210    strukt: Option<String>,
211    #[serde(default)]
212    any: bool,
213    #[serde(flatten)]
214    children: BTreeMap<String, Field>,
215}
216
217#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
218pub struct Argument {
219    #[serde(default)]
220    #[serde(skip_serializing_if = "Required::required_no_message")]
221    pub required: Required,
222    #[serde(rename = "type")]
223    pub argument_type: ArgumentType,
224}
225
226#[derive(Clone, Debug, PartialEq, Eq)]
227pub enum ArgumentType {
228    Any,
229    Bool,
230    Constant(Vec<String>),
231    Display(String),
232    Function,
233    Nil,
234    Number,
235    String,
236    Table,
237    Vararg,
238}
239
240impl Serialize for ArgumentType {
241    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
242        match self {
243            &ArgumentType::Any
244            | &ArgumentType::Bool
245            | &ArgumentType::Function
246            | &ArgumentType::Nil
247            | &ArgumentType::Number
248            | &ArgumentType::String
249            | &ArgumentType::Table
250            | &ArgumentType::Vararg => serializer.serialize_str(&self.to_string()),
251
252            ArgumentType::Constant(constants) => {
253                let mut seq = serializer.serialize_seq(Some(constants.len()))?;
254                for constant in constants {
255                    seq.serialize_element(constant)?;
256                }
257                seq.end()
258            }
259
260            ArgumentType::Display(display) => {
261                let mut map = serializer.serialize_map(Some(1))?;
262                map.serialize_entry("display", display)?;
263                map.end()
264            }
265        }
266    }
267}
268
269impl<'de> Deserialize<'de> for ArgumentType {
270    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
271        deserializer.deserialize_any(ArgumentTypeVisitor)
272    }
273}
274
275struct ArgumentTypeVisitor;
276
277impl<'de> Visitor<'de> for ArgumentTypeVisitor {
278    type Value = ArgumentType;
279
280    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
281        formatter.write_str("an argument type or an array of constant strings")
282    }
283
284    fn visit_map<A: de::MapAccess<'de>>(self, mut access: A) -> Result<Self::Value, A::Error> {
285        let mut map: HashMap<String, String> = HashMap::new();
286
287        while let Some((key, value)) = access.next_entry()? {
288            map.insert(key, value);
289        }
290
291        if let Some(display) = map.remove("display") {
292            Ok(ArgumentType::Display(display))
293        } else {
294            Err(de::Error::custom(
295                "map value must have a `display` property",
296            ))
297        }
298    }
299
300    fn visit_seq<A: de::SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
301        let mut constants = Vec::new();
302
303        while let Some(value) = seq.next_element()? {
304            constants.push(value);
305        }
306
307        Ok(ArgumentType::Constant(constants))
308    }
309
310    fn visit_str<E: de::Error>(self, value: &str) -> Result<Self::Value, E> {
311        match value {
312            "any" => Ok(ArgumentType::Any),
313            "bool" => Ok(ArgumentType::Bool),
314            "function" => Ok(ArgumentType::Function),
315            "nil" => Ok(ArgumentType::Nil),
316            "number" => Ok(ArgumentType::Number),
317            "string" => Ok(ArgumentType::String),
318            "table" => Ok(ArgumentType::Table),
319            "..." => Ok(ArgumentType::Vararg),
320            other => Err(de::Error::custom(format!("unknown type {other}"))),
321        }
322    }
323}
324
325impl fmt::Display for ArgumentType {
326    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
327        match self {
328            ArgumentType::Any => write!(formatter, "any"),
329            ArgumentType::Bool => write!(formatter, "bool"),
330            ArgumentType::Constant(options) => write!(
331                formatter,
332                "{}",
333                // TODO: This gets pretty ugly with a lot of variants
334                options
335                    .iter()
336                    .map(|string| format!("\"{string}\""))
337                    .collect::<Vec<_>>()
338                    .join(", ")
339            ),
340            ArgumentType::Display(display) => write!(formatter, "{display}"),
341            ArgumentType::Function => write!(formatter, "function"),
342            ArgumentType::Nil => write!(formatter, "nil"),
343            ArgumentType::Number => write!(formatter, "number"),
344            ArgumentType::String => write!(formatter, "string"),
345            ArgumentType::Table => write!(formatter, "table"),
346            ArgumentType::Vararg => write!(formatter, "..."),
347        }
348    }
349}
350
351#[derive(Clone, Debug, PartialEq, Eq)]
352pub enum Required {
353    NotRequired,
354    Required(Option<String>),
355}
356
357impl Required {
358    fn required_no_message(&self) -> bool {
359        self == &Required::Required(None)
360    }
361}
362
363impl Default for Required {
364    fn default() -> Self {
365        Required::Required(None)
366    }
367}
368
369impl<'de> Deserialize<'de> for Required {
370    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
371        deserializer.deserialize_any(RequiredVisitor)
372    }
373}
374
375impl Serialize for Required {
376    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
377        match self {
378            Required::NotRequired => serializer.serialize_bool(false),
379            Required::Required(None) => serializer.serialize_bool(true),
380            Required::Required(Some(message)) => serializer.serialize_str(message),
381        }
382    }
383}
384
385struct RequiredVisitor;
386
387impl Visitor<'_> for RequiredVisitor {
388    type Value = Required;
389
390    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
391        formatter.write_str("a boolean or a string message (when required)")
392    }
393
394    fn visit_bool<E: de::Error>(self, value: bool) -> Result<Self::Value, E> {
395        if value {
396            Ok(Required::Required(None))
397        } else {
398            Ok(Required::NotRequired)
399        }
400    }
401
402    fn visit_str<E: de::Error>(self, value: &str) -> Result<Self::Value, E> {
403        Ok(Required::Required(Some(value.to_owned())))
404    }
405}