luaur_analysis/functions/
parse_pattern_string.rs1use crate::records::builtin_types::BuiltinTypes;
2use crate::type_aliases::type_id::TypeId;
3use alloc::vec::Vec;
4use core::ffi::c_char;
5use core::ptr::NonNull;
6
7pub fn parse_pattern_string(
8 builtin_types: NonNull<BuiltinTypes>,
9 data: *const c_char,
10 size: usize,
11) -> Vec<TypeId> {
12 let builtin_types = unsafe { builtin_types.as_ref() };
13 let data = unsafe { core::slice::from_raw_parts(data as *const u8, size) };
14
15 let mut result = Vec::new();
16 let mut depth = 0;
17 let mut parsing_set = false;
18
19 let mut i = 0;
20 while i < size {
21 let b = data[i];
22 if b == b'%' {
23 i += 1;
24 if !parsing_set && i < size && data[i] == b'b' {
25 i += 2;
26 }
27 } else if !parsing_set && b == b'[' {
28 parsing_set = true;
29 if i + 1 < size && data[i + 1] == b']' {
30 i += 1;
31 }
32 } else if parsing_set && b == b']' {
33 parsing_set = false;
34 } else if b == b'(' {
35 if !parsing_set {
36 if i + 1 < size && data[i + 1] == b')' {
37 i += 1;
38 result.push(builtin_types.optionalNumberType);
39 } else {
40 depth += 1;
41 result.push(builtin_types.optionalStringType);
42 }
43 }
44 } else if b == b')' {
45 if !parsing_set {
46 depth -= 1;
47 if depth < 0 {
48 break;
49 }
50 }
51 }
52 i += 1;
53 }
54
55 if depth != 0 || parsing_set {
56 return Vec::new();
57 }
58
59 if result.is_empty() {
60 result.push(builtin_types.optionalStringType);
61 }
62
63 result
64}