vb6parse/parsers/
module.rs

1use crate::{
2    errors::{VB6Error, VB6ErrorKind},
3    language::VB6Token,
4    parsers::VB6Stream,
5    vb6::{keyword_parse, vb6_parse},
6};
7
8use serde::Serialize;
9use winnow::{
10    ascii::{line_ending, space0, space1},
11    token::take_until,
12    Parser,
13};
14
15/// Represents a VB6 module file.
16/// A VB6 module file contains a header and a list of tokens.
17///
18/// The tokens contain the token stream of the code of the class file.
19#[derive(Debug, PartialEq, Eq, Clone, Serialize)]
20pub struct VB6ModuleFile<'a> {
21    pub name: &'a [u8], // Attribute VB_Name = "Module1"
22    pub tokens: Vec<VB6Token<'a>>,
23}
24
25impl<'a> VB6ModuleFile<'a> {
26    /// Parses a VB6 module file from a byte slice.
27    ///
28    /// # Arguments
29    ///
30    /// * `input` The byte slice to parse.
31    ///
32    /// # Returns
33    ///
34    /// A result containing the parsed VB6 module file or an error.
35    ///
36    /// # Errors
37    ///
38    /// An error will be returned if the input is not a valid VB6 module file.
39    ///
40    /// # Panics
41    ///
42    /// This function will panic if the source code is not a valid module file.
43    ///
44    /// # Example
45    ///
46    /// ```rust
47    /// use vb6parse::parsers::VB6ModuleFile;
48    ///
49    /// let input = b"Attribute VB_Name = \"Module1\"
50    /// Option Explicit
51    ///
52    /// Private Sub Class_Initialize()
53    /// End Sub
54    /// ";
55    ///
56    /// let result = VB6ModuleFile::parse("module.bas".to_owned(), input);
57    ///
58    /// assert!(result.is_ok());
59    /// ```
60    pub fn parse(file_name: String, source_code: &'a [u8]) -> Result<Self, VB6Error> {
61        let mut input = VB6Stream::new(file_name, source_code);
62
63        match (
64            space0,
65            keyword_parse("Attribute"),
66            space1,
67            keyword_parse("VB_Name"),
68            space0,
69            "=",
70            space0,
71        )
72            .parse_next(&mut input)
73        {
74            Ok(_) => {}
75            Err(e) => {
76                return Err(input.error(e.into_inner().unwrap()));
77            }
78        }
79
80        let name = match (
81            "\"",
82            take_until(0.., "\""),
83            "\"",
84            space0::<VB6Stream, VB6ErrorKind>,
85            line_ending,
86        )
87            .take()
88            .parse_next(&mut input)
89        {
90            Ok(name) => name,
91            Err(e) => {
92                return Err(input.error(e));
93            }
94        };
95
96        let tokens = match vb6_parse(&mut input) {
97            Ok(tokens) => tokens,
98            Err(e) => {
99                return Err(input.error(e.into_inner().unwrap()));
100            }
101        };
102
103        Ok(VB6ModuleFile { name, tokens })
104    }
105}