1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
use crate::slice::function::Function;
use crate::slice::writer;
use inflector::cases::classcase;
use writer::Writer;


#[derive(Clone, Debug)]
pub struct Interface {
    pub name: String,
    pub functions: Vec<Function>
}

impl Interface {
    pub fn empty() -> Interface {
        Interface {
            name: String::from(""),
            functions: Vec::new()
        }
    }

    pub fn new(name: &str) -> Interface {
        Interface {
            name: String::from(name),
            functions: Vec::new()
        }
    }

    pub fn class_name(&self) -> String {
        classcase::to_class_case(&self.name)
    }

    pub fn add_function(&mut self, function: Function) {
        self.functions.push(function);
    }

    pub fn generate(&self, writer: &mut Writer, mod_path: &str) -> Result<(), Box<dyn std::error::Error>> {
        writer.generate_trait_open(&self.class_name(), Some("IceObject"), 0)?;
        for function in &self.functions {
            function.generate_decl(writer)?;  
        }
        writer.generate_close_block(0)?;

        let prx_name = format!("{}Prx", self.class_name());
        writer.generate_struct_open(&prx_name, 0)?;
        writer.generate_struct_member("proxy", "Proxy", 1)?;
        writer.generate_close_block(0)?;
        writer.blank_line()?;
        
        writer.generate_impl(Some("IceObject"), &prx_name, 0)?;

        writer.write(&format!("const TYPE_ID: &'static str = \"{}::{}\";\n", mod_path, self.name), 1)?;

        writer.generate_fn(
            false, 
            Some(String::from("T: 'static + std::fmt::Debug + std::fmt::Display + FromBytes")),
            "dispatch", 
            vec![
                String::from("&mut self"),
                String::from("op: &str"),
                String::from("mode: u8"),
                String::from("params: &Encapsulation"),
            ],
            Some("Result<ReplyData, Box<dyn std::error::Error>>"),
            true,
            1
        )?;
        writer.write("let id = String::from(self.proxy.ident.clone());\n", 2)?;
        writer.write(&format!("let req = self.proxy.create_request(&id, op, mode, params);\n"), 2)?;
        writer.write("self.proxy.make_request::<T>(&req)\n", 2)?;
        writer.generate_close_block(1)?;
        writer.generate_close_block(0)?;
        writer.blank_line()?;

        writer.generate_impl(Some(&self.class_name()), &prx_name, 0)?;
        for function in &self.functions {
            function.generate_impl(writer)?;  
        }
        writer.generate_close_block(0)?;
        writer.blank_line()?;

        writer.generate_impl(None, &prx_name, 0)?;
        writer.generate_fn(true, None, "checked_cast", vec![String::from("proxy: Proxy")], Some("Result<Self, Box<dyn std::error::Error>>"), true, 1)?;
        writer.write("let mut my_proxy = Self {\n", 2)?;
        writer.write("proxy: proxy,\n", 3)?;
        writer.write("};\n", 2)?;
        writer.blank_line()?;

        writer.write("if !my_proxy.ice_is_a()? {\n", 2)?;
        writer.write("return Err(Box::new(ProtocolError::new(\"ice_is_a() failed\")));\n", 3)?;
        writer.generate_close_block(2)?;
        writer.write("Ok(my_proxy)\n", 2)?;

        writer.generate_close_block(1)?;
        writer.generate_close_block(0)?;
        writer.blank_line()?;
        Ok(())
    }
}