gbf_core/decompiler/ast/
meta.rs

1#![deny(missing_docs)]
2
3use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5
6/// Represents a metadata node in the AST
7#[derive(Debug, Clone, Serialize, Deserialize, Eq, Default)]
8pub struct Metadata {
9    comments: Vec<String>,
10    properties: HashMap<String, String>,
11}
12
13impl Metadata {
14    /// Returns the comments.
15    pub fn comments(&self) -> &Vec<String> {
16        &self.comments
17    }
18
19    /// Adds a new comment
20    pub fn add_comment(&mut self, comment: String) {
21        self.comments.push(comment);
22    }
23
24    /// Adds a new property
25    pub fn add_property(&mut self, key: String, value: String) {
26        self.properties.insert(key, value);
27    }
28
29    /// Gets a property
30    pub fn get_property(&self, key: &str) -> Option<&String> {
31        self.properties.get(key)
32    }
33
34    /// Returns the properties.
35    pub fn properties(&self) -> &HashMap<String, String> {
36        &self.properties
37    }
38}
39
40impl PartialEq for Metadata {
41    fn eq(&self, other: &Self) -> bool {
42        self.comments == other.comments && self.properties == other.properties
43    }
44}
45
46#[cfg(test)]
47mod tests {
48    use crate::decompiler::ast::{
49        assignment::AssignmentNode, emit, new_assignment, new_id, new_if, ptr::P,
50    };
51
52    use super::*;
53
54    #[test]
55    fn test_metadata() {
56        let mut metadata = Metadata::default();
57        metadata.add_comment("This is a comment".to_string());
58        metadata.add_property("key".to_string(), "value".to_string());
59
60        assert_eq!(metadata.comments(), &vec!["This is a comment".to_string()]);
61        assert_eq!(metadata.get_property("key"), Some(&"value".to_string()));
62    }
63
64    #[test]
65    fn test_attach_metadata() {
66        let mut stmt: P<AssignmentNode> = new_assignment(new_id("foo"), new_id("bar")).into();
67        stmt.metadata_mut()
68            .add_comment("This is a comment".to_string());
69
70        // Create if stmt
71        let if_node = new_if(new_id("test"), vec![stmt]);
72
73        let emitted = emit(if_node);
74        assert_eq!(
75            emitted,
76            "if (test) \n{\n    // This is a comment\n    foo = bar;\n}"
77        );
78    }
79}