pub fn generate_interface<'a, W: Write>(
        &self,
        interface: &Interface,
        req_index: usize,
        resp_index: usize,
        sink: &'a mut W,
    ) -> Result<(usize, usize)> {
        let mut messages: Vec<TypedMessage> = vec![];

        writeln!(
            sink,
            "class {}Session extends SessionObject {{",
            interface.name
        )?;
        writeln!(sink, "constructor(object_id, service_id, session) {{")?;
        writeln!(
            sink,
            "super(object_id , session, service_id, {}Messages);",
            interface.name
        )?;
        writeln!(sink, "this.service_id = service_id;")?;

        if !interface.events.is_empty() {
            writeln!(sink, "session.track_events(service_id, object_id, this);")?;
        }

        writeln!(sink, "}}")?;

        let mut resp_count = resp_index;

        // Methods
        for method in interface.methods.values() {
            let (req, resp) = MethodWriter::declare(&method, sink)?;
            writeln!(sink, "{{")?;

            writeln!(
                sink,
                "return this.call_method(\"{}\", {{",
                method.name.to_camel_case()
            )?;
            let mut first = true;
            for param in &method.params {
                if !first {
                    write!(sink, ",")?;
                }
                first = false;
                write!(sink, "{}: {}", param.name, param.name)?;
            }
            writeln!(sink, "}});")?;
            writeln!(sink, "}}")?;

            messages.push(req);
            messages.push(resp);
            resp_count += 2; // Adding 2 because there are success and error responses.
        }

        // Members
        for member in &interface.members {
            let member = member.1;
            let camel_name = member.name.to_camel_case();

            // Getter: get xxx()
            // These are infallible.
            writeln!(sink, "get {}() {{", member.name)?;
            writeln!(sink, "return this.call_method(\"Get{}\");", camel_name)?;
            writeln!(sink, "}}")?;

            let typed_getter = TypedRequest::new(&format!("Get{}", camel_name));
            // No parameter sent for the request.
            messages.push(TypedMessage::Request(typed_getter));

            // Using the member type for the getter response.
            let mut typed_getter = TypedResponse::new(&format!("Get{}", camel_name));
            typed_getter.success = Some(TypeItem::from(None, &member.typ));
            messages.push(TypedMessage::Response(typed_getter));
            resp_count += 1;

            // Setter: set xxx(value)
            // These are infallible.
            writeln!(sink, "set {}(value) {{", member.name)?;
            writeln!(
                sink,
                "return this.call_method_oneway(\"Set{}\", {{ value }});",
                camel_name
            )?;
            writeln!(sink, "}}")?;

            let mut typed_setter = TypedRequest::new(&format!("Set{}", camel_name));
            // Using the member type for the setter request.
            typed_setter
                .types
                .push(TypeItem::from(Some("value".into()), &member.typ));
            messages.push(TypedMessage::Request(typed_setter));
        }

        // Generate the event dispatching code if this interface has events.
        if !interface.events.is_empty() {
            writeln!(sink, "on_event(event) {{")?;
            writeln!(
                sink,
                "// console.log(`{}Session message: ${{event}}`);",
                interface.name
            )?;
            writeln!(sink, "let decoder = new Decoder(event);")?;
            writeln!(sink, "let variant = decoder.enum_tag();")?;
            for (i, event) in interface.events.iter().enumerate() {
                let event = event.1;
                writeln!(sink, "// Event #{}: {}", i + resp_count, event.name)?;
                if i != 0 {
                    write!(sink, "else ")?;
                }
                writeln!(sink, "if (variant == {}) {{", i + resp_count)?;
                writeln!(sink, "let result = null;")?;
                let rtype = TypeItem::from(None, &event.returns);
                self.write_decoder_for_item(&rtype, sink, "result", 0)?;

                writeln!(sink, "this.dispatchEvent({}, result);", i)?;
                writeln!(sink, "}}")?;
            }
            writeln!(
                sink,
                "else {{\n console.error(`Unable to process variant #${{variant}}`); }}"
            )?;
            writeln!(sink, "}}")?; // End on_event(event) ...
        }

        writeln!(sink, "}}\n")?; // End class {}Session ...

        // Create constants for the events name.
        for (i, event) in interface.events.iter().enumerate() {
            writeln!(
                sink,
                "{}Session.prototype.{}_EVENT = {};",
                interface.name, event.1.name, i
            )?;
        }

        // Debug
        write!(sink, "/*\n\n")?;
        write!(sink, "Messages: {:?}\n\n", messages)?;
        write!(sink, "*/\n\n")?;

        let res = self.generate_messages_for_interface(
            &interface.name,
            &messages,
            req_index,
            resp_index,
            sink,
        )?;

        // Increment the response index by the number of events since they are part
        // of the response set.
        Ok((res.0, res.1 + interface.events.len()))
    }
// Interfaces are mapped to a class extending SessionObject.
// Returns the updated index for requests and responses.
Interfaces are mapped to a class extending SessionObject.
Returns the updated index for requests and responses.
Interfaces are mapped to a class extending SessionObject . Returns the updated index for requests and responses .
pub fn generate_interface<'a, W: Write>(
        &self,
        interface: &Interface,
        req_index: usize,
        resp_index: usize,
        sink: &'a mut W,
    ) -> Result<(usize, usize)> {
        let mut messages: Vec<TypedMessage> = vec![];
        writeln!(
            sink,
            "class {}Session extends SessionObject {{",
            interface.name
        )?;
        writeln!(sink, "constructor(object_id, service_id, session) {{")?;
        writeln!(
            sink,
            "super(object_id , session, service_id, {}Messages);",
            interface.name
        )?;
        writeln!(sink, "this.service_id = service_id;")?;
        if !interface.events.is_empty() {
            writeln!(sink, "session.track_events(service_id, object_id, this);")?;
        }
        writeln!(sink, "}}")?;
        let mut resp_count = resp_index;
        // Methods
        for method in interface.methods.values() {
            let (req, resp) = MethodWriter::declare(&method, sink)?;
            writeln!(sink, "{{")?;
            writeln!(
                sink,
                "return this.call_method(\"{}\", {{",
                method.name.to_camel_case()
            )?;
            let mut first = true;
            for param in &method.params {
                if !first {
                    write!(sink, ",")?;
                }
                first = false;
                write!(sink, "{}: {}", param.name, param.name)?;
            }
            writeln!(sink, "}});")?;
            writeln!(sink, "}}")?;
            messages.push(req);
            messages.push(resp);
            resp_count += 2; // Adding 2 because there are success and error responses.
        }
        // Members
        for member in &interface.members {
            let member = member.1;
            let camel_name = member.name.to_camel_case();
            // Getter: get xxx()
            // These are infallible.
            writeln!(sink, "get {}() {{", member.name)?;
            writeln!(sink, "return this.call_method(\"Get{}\");", camel_name)?;
            writeln!(sink, "}}")?;
            let typed_getter = TypedRequest::new(&format!("Get{}", camel_name));
            // No parameter sent for the request.
            messages.push(TypedMessage::Request(typed_getter));
            // Using the member type for the getter response.
            let mut typed_getter = TypedResponse::new(&format!("Get{}", camel_name));
            typed_getter.success = Some(TypeItem::from(None, &member.typ));
            messages.push(TypedMessage::Response(typed_getter));
            resp_count += 1;
            // Setter: set xxx(value)
            // These are infallible.
            writeln!(sink, "set {}(value) {{", member.name)?;
            writeln!(
                sink,
                "return this.call_method_oneway(\"Set{}\", {{ value }});",
                camel_name
            )?;
            writeln!(sink, "}}")?;
            let mut typed_setter = TypedRequest::new(&format!("Set{}", camel_name));
            // Using the member type for the setter request.
            typed_setter
                .types
                .push(TypeItem::from(Some("value".into()), &member.typ));
            messages.push(TypedMessage::Request(typed_setter));
        }
        // Generate the event dispatching code if this interface has events.
        if !interface.events.is_empty() {
            writeln!(sink, "on_event(event) {{")?;
            writeln!(
                sink,
                "// console.log(`{}Session message: ${{event}}`);",
                interface.name
            )?;
            writeln!(sink, "let decoder = new Decoder(event);")?;
            writeln!(sink, "let variant = decoder.enum_tag();")?;
            for (i, event) in interface.events.iter().enumerate() {
                let event = event.1;
                writeln!(sink, "// Event #{}: {}", i + resp_count, event.name)?;
                if i != 0 {
                    write!(sink, "else ")?;
                }
                writeln!(sink, "if (variant == {}) {{", i + resp_count)?;
                writeln!(sink, "let result = null;")?;
                let rtype = TypeItem::from(None, &event.returns);
                self.write_decoder_for_item(&rtype, sink, "result", 0)?;
                writeln!(sink, "this.dispatchEvent({}, result);", i)?;
                writeln!(sink, "}}")?;
            }
            writeln!(
                sink,
                "else {{\n console.error(`Unable to process variant #${{variant}}`); }}"
            )?;
            writeln!(sink, "}}")?; // End on_event(event) ...
        }
        writeln!(sink, "}}\n")?; // End class {}Session ...
        // Create constants for the events name.
        for (i, event) in interface.events.iter().enumerate() {
            writeln!(
                sink,
                "{}Session.prototype.{}_EVENT = {};",
                interface.name, event.1.name, i
            )?;
        }
        // Debug
        write!(sink, "/*\n\n")?;
        write!(sink, "Messages: {:?}\n\n", messages)?;
        write!(sink, "*/\n\n")?;
        let res = self.generate_messages_for_interface(
            &interface.name,
            &messages,
            req_index,
            resp_index,
            sink,
        )?;
        // Increment the response index by the number of events since they are part
        // of the response set.
        Ok((res.0, res.1 + interface.events.len()))
    }
pub fn generate_interface < ' a , W : Write > ( & self , interface : & Interface , req_index : usize , resp_index : usize , sink : & ' a mut W , ) -> Result < ( usize , usize ) > { let mut messages : Vec < TypedMessage > = vec ! [ ] ; writeln ! ( sink " " interface name ) ? ; writeln ! ( sink " " ) ? ; writeln ! ( sink " " interface name ) ? ; writeln ! ( sink " " ) ? ; if ! interface . events . is_empty ( ) { writeln ! ( sink " " ) ? ; } writeln ! ( sink " " ) ? ; let mut resp_count = resp_index ; // Methods for method in interface . methods . values ( ) { let ( req , resp ) = MethodWriter :: declare ( & method , sink ) ? ; writeln ! ( sink " " ) ? ; writeln ! ( sink " \" \" " method name to_camel_case ( ) ) ? ; let mut first = true ; for param in & method . params { if ! first { write ! ( sink " " ) ? ; } first = false ; write ! ( sink " " param name param name ) ? ; } writeln ! ( sink " " ) ? ; writeln ! ( sink " " ) ? ; messages . push ( req ) ; messages . push ( resp ) ; resp_count += 2 ; // Adding 2 because there are success and error responses. } // Members for member in & interface . members { let member = member . 1 ; let camel_name = member . name . to_camel_case ( ) ; // Getter: get xxx() // These are infallible. writeln ! ( sink " " member name ) ? ; writeln ! ( sink " \" \" " camel_name ) ? ; writeln ! ( sink " " ) ? ; let typed_getter = TypedRequest :: new ( & format ! ( " " camel_name ) ) ; // No parameter sent for the request. messages . push ( TypedMessage :: Request ( typed_getter ) ) ; // Using the member type for the getter response. let mut typed_getter = TypedResponse :: new ( & format ! ( " " camel_name ) ) ; typed_getter . success = Some ( TypeItem :: from ( None , & member . typ ) ) ; messages . push ( TypedMessage :: Response ( typed_getter ) ) ; resp_count += 1 ; // Setter: set xxx(value) // These are infallible. writeln ! ( sink " " member name ) ? ; writeln ! ( sink " \" \" " camel_name ) ? ; writeln ! ( sink " " ) ? ; let mut typed_setter = TypedRequest :: new ( & format ! ( " " camel_name ) ) ; // Using the member type for the setter request. typed_setter . types . push ( TypeItem :: from ( Some ( " " . into ( ) ) , & member . typ ) ) ; messages . push ( TypedMessage :: Request ( typed_setter ) ) ; } // Generate the event dispatching code if this interface has events. if ! interface . events . is_empty ( ) { writeln ! ( sink " " ) ? ; writeln ! ( sink " " interface name ) ? ; writeln ! ( sink " " ) ? ; writeln ! ( sink " " ) ? ; for ( i , event ) in interface . events . iter ( ) . enumerate ( ) { let event = event . 1 ; writeln ! ( sink " " i resp_count event name ) ? ; if i != 0 { write ! ( sink " " ) ? ; } writeln ! ( sink " " i resp_count ) ? ; writeln ! ( sink " " ) ? ; let rtype = TypeItem :: from ( None , & event . returns ) ; self . write_decoder_for_item ( & rtype , sink , " " , 0 ) ? ; writeln ! ( sink " " i ) ? ; writeln ! ( sink " " ) ? ; } writeln ! ( sink " \n " ) ? ; writeln ! ( sink " " ) ? ; // End on_event(event) ... } writeln ! ( sink " \n " ) ? ; // End class {}Session ... // Create constants for the events name. for ( i , event ) in interface . events . iter ( ) . enumerate ( ) { writeln ! ( sink " " interface name event 1 name i ) ? ; } // Debug write ! ( sink " \n \n " ) ? ; write ! ( sink " \n \n " messages ) ? ; write ! ( sink " \n \n " ) ? ; let res = self . generate_messages_for_interface ( & interface . name , & messages , req_index , resp_index , sink , ) ? ; // Increment the response index by the number of events since they are part // of the response set. Ok ( ( res . 0 , res . 1 + interface . events . len ( ) ) ) }
Interfaces are mapped to a class extending SessionObject.
Interfaces are mapped to a class extending SessionObject .
&self
interface
&Interface
req_index
usize
resp_index
usize
sink
&'a mut W
&self
interface
&Interface
req_index
usize
resp_index
usize
sink
&'a mut W