// Callbacks are mapped to a class extending SessionObject.
// Returns the updated index for requests and responses.
Callbacks are mapped to a class extending SessionObject.
Returns the updated index for requests and responses.
Callbacks are mapped to a class extending SessionObject . Returns the updated index for requests and responses .
pub fn generate_callback<'a, W: Write>(
        &self,
        callback: &Callback,
        req_index: usize,
        resp_index: usize,
        sink: &'a mut W,
    ) -> Result<(usize, usize)> {
        writeln!(
            sink,
            "export class {}Base extends SessionObject {{",
            callback.name
        )?;
        writeln!(sink, "constructor(service_id, session) {{")?;
        writeln!(sink, "super(session.next_id , session, service_id, null);")?;
        writeln!(sink, "session.track(this);")?;
        writeln!(sink, "this.service_id = service_id;")?;
        writeln!(sink, "}}")?;
        // Callback base classes don't implement methods themselves, since
        // they are expected to be implemented by the user.
        // The base class implements a dispatcher to call these methods
        // when a message is received and manages the response sending when
        // the method promise resolves or rejects.
        // The message dispatcher
        writeln!(
            sink,
            r#"on_message(message) {{
            console.log(`Message for {} ${{this.display()}}: %o`, message);"#,
            callback.name
        )?;
        writeln!(
            sink,
            r#"let decoder = new Decoder(message.content);
        let variant = decoder.enum_tag();
        console.log(`Starting at index {}`);
        console.log(`we got variant ${{variant}}`);
        // Dispatch based on message.content which is the real payload.
        "#,
            resp_index
        )?;
        let mut resp_index = resp_index;
        let mut req_index = req_index;
        writeln!(sink, "switch (variant) {{")?;
        for method in callback.methods.values() {
            let (req, resp) = MethodWriter::get_types(&method)?;
            let req = match req {
                TypedMessage::Request(req) => req,
                _ => panic!("Expected TypedMessage::Request!"),
            };
            let resp = match resp {
                TypedMessage::Response(resp) => resp,
                _ => panic!("Expected TypedMessage::Response!"),
            };
            writeln!(sink, "case {}: {{", resp_index)?;
            writeln!(
                sink,
                "console.log(`Extracting parameters for {}(...)`);",
                method.name
            )?;
            writeln!(
                sink,
                "if (this.{} && this.{} instanceof Function) {{",
                method.name, method.name
            )?;
            // Decode the parameters, storing them in a temp struct.
            writeln!(sink, "let result = {{}};")?;
            for item in &req.types {
                self.write_decoder_for_item(&item, sink, "result", 0)?;
            }
            writeln!(sink, "let output = this.{}(", method.name)?;
            let mut first = true;
            for item in &req.types {
                if !first {
                    write!(sink, ",")?;
                }
                first = false;
                match item.typ.typ {
                    ConcreteType::Dictionary(_)
                    | ConcreteType::Interface(_)
                    | ConcreteType::Enumeration(_) => writeln!(sink, "result")?,
                    _ => writeln!(sink, "result.{}", item.name.clone().unwrap())?,
                }
            }
            writeln!(sink, ");")?;
            // output is a Promise, decode the resolved or rejected value and
            // send it back.
            writeln!(sink, "output.then(")?;
            // Success case.
            writeln!(
                sink,
                "success => {{ console.log(`{}.{} success: ${{success}}`);",
                callback.name, method.name
            )?;
            writeln!(sink, "let encoder = new Encoder();")?;
            writeln!(sink, "let result = encoder.enum_tag({});", req_index)?;
            req_index += 1;
            // generate the encoder for the success payload.
            self.write_encoder_for_item("success", &resp.success.unwrap(), sink)?;
            // Send the message.
            writeln!(sink, "message.content = result.value();")?;
            writeln!(sink, "this.send_callback_message(message);")?;
            writeln!(sink, "}},")?;
            // Error case.
            writeln!(
                sink,
                "error => {{ console.error(`{}.{} error: ${{error}}`);",
                callback.name, method.name
            )?;
            writeln!(sink, "let encoder = new Encoder();")?;
            writeln!(sink, "let result = encoder.enum_tag({});", req_index)?;
            req_index += 1;
            // generate the encoder for the error payload.
            self.write_encoder_for_item("error", &resp.error.unwrap(), sink)?;
            // Send the message.
            writeln!(sink, "message.content = result.value();")?;
            writeln!(sink, "this.send_callback_message(message);")?;
            writeln!(sink, "}}")?;
            writeln!(sink, ");")?; // End of output.then(
            writeln!(sink, "}}")?; // End if (this...)
            writeln!(sink, "break; }}")?; // End case $variant...
            resp_index += 1;
            // messages.push(resp);
            // messages.push(req);
        }
        writeln!(
            sink,
            "default: console.error(`Unexpected variant: ${{variant}}`);"
        )?;
        writeln!(sink, "}}")?; // End switch (variant)
        writeln!(sink, "}}")?; // End on_message(..)
        writeln!(sink, "}}\n")?; // End class {}Base ...
        Ok((req_index, resp_index))
    }
pub fn generate_callback < ' a , W : Write > ( & self , callback : & Callback , req_index : usize , resp_index : usize , sink : & ' a mut W , ) -> Result < ( usize , usize ) > { writeln ! ( sink " " callback name ) ? ; writeln ! ( sink " " ) ? ; writeln ! ( sink " " ) ? ; writeln ! ( sink " " ) ? ; writeln ! ( sink " " ) ? ; writeln ! ( sink " " ) ? ; // Callback base classes don't implement methods themselves, since // they are expected to be implemented by the user. // The base class implements a dispatcher to call these methods // when a message is received and manages the response sending when // the method promise resolves or rejects. // The message dispatcher writeln ! ( sink r#"on_message(message) {{
            console.log(`Message for {} ${{this.display()}}: %o`, message);"# callback name ) ? ; writeln ! ( sink r#"let decoder = new Decoder(message.content);
        let variant = decoder.enum_tag();
        console.log(`Starting at index {}`);
        console.log(`we got variant ${{variant}}`);
        // Dispatch based on message.content which is the real payload.
        "# resp_index ) ? ; let mut resp_index = resp_index ; let mut req_index = req_index ; writeln ! ( sink " " ) ? ; for method in callback . methods . values ( ) { let ( req , resp ) = MethodWriter :: get_types ( & method ) ? ; let req = match req { TypedMessage :: Request ( req ) => req , _ => panic ! ( " " ) , } ; let resp = match resp { TypedMessage :: Response ( resp ) => resp , _ => panic ! ( " " ) , } ; writeln ! ( sink " " resp_index ) ? ; writeln ! ( sink " " method name ) ? ; writeln ! ( sink " " method name method name ) ? ; // Decode the parameters, storing them in a temp struct. writeln ! ( sink " " ) ? ; for item in & req . types { self . write_decoder_for_item ( & item , sink , " " , 0 ) ? ; } writeln ! ( sink " " method name ) ? ; let mut first = true ; for item in & req . types { if ! first { write ! ( sink " " ) ? ; } first = false ; match item . typ . typ { ConcreteType :: Dictionary ( _ ) | ConcreteType :: Interface ( _ ) | ConcreteType :: Enumeration ( _ ) => writeln ! ( sink " " ) ? , _ => writeln ! ( sink " " item name clone ( ) unwrap ( ) ) ? , } } writeln ! ( sink " " ) ? ; // output is a Promise, decode the resolved or rejected value and // send it back. writeln ! ( sink " " ) ? ; // Success case. writeln ! ( sink " " callback name method name ) ? ; writeln ! ( sink " " ) ? ; writeln ! ( sink " " req_index ) ? ; req_index += 1 ; // generate the encoder for the success payload. self . write_encoder_for_item ( " " , & resp . success . unwrap ( ) , sink ) ? ; // Send the message. writeln ! ( sink " " ) ? ; writeln ! ( sink " " ) ? ; writeln ! ( sink " " ) ? ; // Error case. writeln ! ( sink " " callback name method name ) ? ; writeln ! ( sink " " ) ? ; writeln ! ( sink " " req_index ) ? ; req_index += 1 ; // generate the encoder for the error payload. self . write_encoder_for_item ( " " , & resp . error . unwrap ( ) , sink ) ? ; // Send the message. writeln ! ( sink " " ) ? ; writeln ! ( sink " " ) ? ; writeln ! ( sink " " ) ? ; writeln ! ( sink " " ) ? ; // End of output.then( writeln ! ( sink " " ) ? ; // End if (this...) writeln ! ( sink " " ) ? ; // End case $variant... resp_index += 1 ; // messages.push(resp); // messages.push(req); } writeln ! ( sink " " ) ? ; writeln ! ( sink " " ) ? ; // End switch (variant) writeln ! ( sink " " ) ? ; // End on_message(..) writeln ! ( sink " \n " ) ? ; // End class {}Base ... Ok ( ( req_index , resp_index ) ) }
Callbacks are mapped to a class extending SessionObject.
Callbacks are mapped to a class extending SessionObject .
&self
callback
&Callback
req_index
usize
resp_index
usize
sink
&'a mut W