rujag/java/
generatable.rs

1use crate::java::*;
2use crate::tools::*;
3
4pub trait Generatable {
5    fn generate(&self) -> Result<String, String>;
6}
7
8impl Generatable for JVariable {
9    fn generate(&self) -> Result<String, String> {
10        let jstatic = if self.is_static() { "static" } else { "" };
11        let jfinal = if self.is_final() { "final" } else { "" };
12        let mut s = format!("{} {} {} {} {};", self.access(), jstatic, jfinal, self.jtype(), self.name());
13        s = s.trim().to_string();
14        s = s.remove_duplicate_spaces();
15        Ok(s)
16    }
17}
18
19impl Generatable for JMethod {
20    fn generate(&self) -> Result<String, String> {
21        let jstatic = if self.is_static() { "static" } else { "" };
22        let jfinal = if self.is_final() { "final" } else { "" };
23        let parameters: Vec<String> = self.args().iter()
24            .map(|(name, jtype)| format!("{} {}", jtype, name))
25            .collect();
26        let parameters = parameters.join(", ");
27        let head = format!("{} {} {} {} {}({}) {{", self.access(), jstatic, jfinal, self.return_type(), self.name(), parameters);
28        let head = head.trim().to_string();
29        let head = head.remove_duplicate_spaces();
30        Ok(format!("{}\n{}\n}}", head, self.src().clone().indent(4)))
31    }
32}
33
34impl Generatable for JClass {
35    fn generate(&self) -> Result<String, String> {
36        let jfinal = if self.is_final() { "final" } else { "" };
37        let head = format!("{} {} class {} {{", self.access(), jfinal, self.name());
38        let fields: Vec<String> = self.fields().iter()
39            .map(|f| f.generate().unwrap())
40            .collect();
41        let fields = fields.join("\n\n");
42        let methods: Vec<String> = self.methods().iter()
43            .map(|m| m.generate().unwrap())
44            .collect();
45        let methods = methods.join("\n\n");
46        let body = format!("{}\n{}", fields, methods);
47        Ok((format!(
48"package {};
49
50{}
51
52{}
53}}", self.package(), head, body)))
54    }
55}
56
57mod tests {
58    use crate::java::*;
59
60    #[test]
61    fn default_int() {
62        let v = JVariable::new(
63            "di",
64            JType::Primitive(JPrimitive::Int),
65            JAccessModifier::Default,
66            false,
67            false,
68        );
69        let expected = "int di;";
70        assert_eq!(expected, v.generate().unwrap());
71    }
72
73    #[test]
74    fn public_static_final_string() {
75        let v = JVariable::new(
76            "psfs",
77            JType::Class("String".to_string()),
78            JAccessModifier::Public,
79            true,
80            true,
81        );
82        let expected = "public static final String psfs;";
83        assert_eq!(expected, v.generate().unwrap());
84    }
85
86    #[test]
87    fn public_static_final_boolean_method() {
88        let args = vec![
89            ("v1".to_string(), JType::Class("String".to_string())),
90            ("v2".to_string(), JType::Primitive(JPrimitive::Int)),
91        ];
92        let m = JMethod::new(
93            "stringEqualsInt".to_string(),
94            "boolean equal = Integer.parseInt(v2).equals(v1);\nreturn equal;".to_string(),
95            args,
96            JType::Primitive(JPrimitive::Boolean),
97            JAccessModifier::Public,
98            true,
99            true,
100        );
101        let expected =
102"public static final boolean stringEqualsInt(String v1, int v2) {
103    boolean equal = Integer.parseInt(v2).equals(v1);
104    return equal;
105}";
106        assert_eq!(expected, m.generate().unwrap());
107    }
108}