pub fn on_canister_result(
        &mut self,
        call_context_id: CallContextId,
        result: Result<Option<WasmResult>, HypervisorError>,
    ) -> CallContextAction {
        enum OutstandingCalls {
            Yes,
            No,
        }
        enum Responded {
            Yes,
            No,
        }

        let outstanding_calls = if self.outstanding_calls(call_context_id) > 0 {
            OutstandingCalls::Yes
        } else {
            OutstandingCalls::No
        };

        let context = self
            .call_contexts
            .get_mut(&call_context_id)
            .unwrap_or_else(|| panic!("no call context for id={} found", call_context_id));
        let responded = if context.responded {
            Responded::Yes
        } else {
            Responded::No
        };

        // This is one big match instead of a few if statements because we want
        // the compiler to tell us if we handled all the possible cases.
        match (result, responded, outstanding_calls) {
            (Ok(None), Responded::No, OutstandingCalls::Yes)
            | (Err(_), Responded::No, OutstandingCalls::Yes) => CallContextAction::NotYetResponded,

            (Ok(None), Responded::Yes, OutstandingCalls::Yes)
            | (Err(_), Responded::Yes, OutstandingCalls::Yes) => {
                CallContextAction::AlreadyResponded
            }
            (Ok(None), Responded::Yes, OutstandingCalls::No)
            | (Err(_), Responded::Yes, OutstandingCalls::No) => {
                self.call_contexts.remove(&call_context_id);
                CallContextAction::AlreadyResponded
            }

            (Ok(None), Responded::No, OutstandingCalls::No) => {
                let refund = context.available_cycles;
                self.call_contexts.remove(&call_context_id);
                CallContextAction::NoResponse { refund }
            }

            (Ok(Some(WasmResult::Reply(payload))), Responded::No, OutstandingCalls::No) => {
                let refund = context.available_cycles;
                self.call_contexts.remove(&call_context_id);
                CallContextAction::Reply { payload, refund }
            }
            (Ok(Some(WasmResult::Reply(payload))), Responded::No, OutstandingCalls::Yes) => {
                context.responded = true;
                CallContextAction::Reply {
                    payload,
                    refund: context.available_cycles,
                }
            }

            (Ok(Some(WasmResult::Reject(payload))), Responded::No, OutstandingCalls::No) => {
                let refund = context.available_cycles;
                self.call_contexts.remove(&call_context_id);
                CallContextAction::Reject { payload, refund }
            }
            (Ok(Some(WasmResult::Reject(payload))), Responded::No, OutstandingCalls::Yes) => {
                context.responded = true;
                CallContextAction::Reject {
                    payload,
                    refund: context.available_cycles,
                }
            }

            (Err(error), Responded::No, OutstandingCalls::No) => {
                let refund = context.available_cycles;
                self.call_contexts.remove(&call_context_id);
                CallContextAction::Fail { error, refund }
            }

            // The following can never happen since we handle at the SystemApi level if a canister
            // tries to reply to an already responded call context.
            (Ok(Some(WasmResult::Reply(_))), Responded::Yes, _) => unreachable!(
                "Canister replied twice on the same request, call_context_id = {}",
                call_context_id
            ),
            (Ok(Some(WasmResult::Reject(_))), Responded::Yes, _) => unreachable!(
                "Canister replied twice on the same request, call_context_id = {}",
                call_context_id
            ),
        }
    }
/// Accepts a canister result and produces an action that should be taken
/// by the caller.
Accepts a canister result and produces an action that should be taken
by the caller.
Accepts a canister result and produces an action that should be taken by the caller .
pub fn on_canister_result(
        &mut self,
        call_context_id: CallContextId,
        result: Result<Option<WasmResult>, HypervisorError>,
    ) -> CallContextAction {
        enum OutstandingCalls {
            Yes,
            No,
        }
        enum Responded {
            Yes,
            No,
        }
        let outstanding_calls = if self.outstanding_calls(call_context_id) > 0 {
            OutstandingCalls::Yes
        } else {
            OutstandingCalls::No
        };
        let context = self
            .call_contexts
            .get_mut(&call_context_id)
            .unwrap_or_else(|| panic!("no call context for id={} found", call_context_id));
        let responded = if context.responded {
            Responded::Yes
        } else {
            Responded::No
        };
        // This is one big match instead of a few if statements because we want
        // the compiler to tell us if we handled all the possible cases.
        match (result, responded, outstanding_calls) {
            (Ok(None), Responded::No, OutstandingCalls::Yes)
            | (Err(_), Responded::No, OutstandingCalls::Yes) => CallContextAction::NotYetResponded,
            (Ok(None), Responded::Yes, OutstandingCalls::Yes)
            | (Err(_), Responded::Yes, OutstandingCalls::Yes) => {
                CallContextAction::AlreadyResponded
            }
            (Ok(None), Responded::Yes, OutstandingCalls::No)
            | (Err(_), Responded::Yes, OutstandingCalls::No) => {
                self.call_contexts.remove(&call_context_id);
                CallContextAction::AlreadyResponded
            }
            (Ok(None), Responded::No, OutstandingCalls::No) => {
                let refund = context.available_cycles;
                self.call_contexts.remove(&call_context_id);
                CallContextAction::NoResponse { refund }
            }
            (Ok(Some(WasmResult::Reply(payload))), Responded::No, OutstandingCalls::No) => {
                let refund = context.available_cycles;
                self.call_contexts.remove(&call_context_id);
                CallContextAction::Reply { payload, refund }
            }
            (Ok(Some(WasmResult::Reply(payload))), Responded::No, OutstandingCalls::Yes) => {
                context.responded = true;
                CallContextAction::Reply {
                    payload,
                    refund: context.available_cycles,
                }
            }
            (Ok(Some(WasmResult::Reject(payload))), Responded::No, OutstandingCalls::No) => {
                let refund = context.available_cycles;
                self.call_contexts.remove(&call_context_id);
                CallContextAction::Reject { payload, refund }
            }
            (Ok(Some(WasmResult::Reject(payload))), Responded::No, OutstandingCalls::Yes) => {
                context.responded = true;
                CallContextAction::Reject {
                    payload,
                    refund: context.available_cycles,
                }
            }
            (Err(error), Responded::No, OutstandingCalls::No) => {
                let refund = context.available_cycles;
                self.call_contexts.remove(&call_context_id);
                CallContextAction::Fail { error, refund }
            }
            // The following can never happen since we handle at the SystemApi level if a canister
            // tries to reply to an already responded call context.
            (Ok(Some(WasmResult::Reply(_))), Responded::Yes, _) => unreachable!(
                "Canister replied twice on the same request, call_context_id = {}",
                call_context_id
            ),
            (Ok(Some(WasmResult::Reject(_))), Responded::Yes, _) => unreachable!(
                "Canister replied twice on the same request, call_context_id = {}",
                call_context_id
            ),
        }
    }
pub fn on_canister_result ( & mut self , call_context_id : CallContextId , result : Result < Option < WasmResult > , HypervisorError > , ) -> CallContextAction { enum OutstandingCalls { Yes , No , } enum Responded { Yes , No , } let outstanding_calls = if self . outstanding_calls ( call_context_id ) > 0 { OutstandingCalls :: Yes } else { OutstandingCalls :: No } ; let context = self . call_contexts . get_mut ( & call_context_id ) . unwrap_or_else ( | | panic ! ( " " call_context_id ) ) ; let responded = if context . responded { Responded :: Yes } else { Responded :: No } ; // This is one big match instead of a few if statements because we want // the compiler to tell us if we handled all the possible cases. match ( result , responded , outstanding_calls ) { ( Ok ( None ) , Responded :: No , OutstandingCalls :: Yes ) | ( Err ( _ ) , Responded :: No , OutstandingCalls :: Yes ) => CallContextAction :: NotYetResponded , ( Ok ( None ) , Responded :: Yes , OutstandingCalls :: Yes ) | ( Err ( _ ) , Responded :: Yes , OutstandingCalls :: Yes ) => { CallContextAction :: AlreadyResponded } ( Ok ( None ) , Responded :: Yes , OutstandingCalls :: No ) | ( Err ( _ ) , Responded :: Yes , OutstandingCalls :: No ) => { self . call_contexts . remove ( & call_context_id ) ; CallContextAction :: AlreadyResponded } ( Ok ( None ) , Responded :: No , OutstandingCalls :: No ) => { let refund = context . available_cycles ; self . call_contexts . remove ( & call_context_id ) ; CallContextAction :: NoResponse { refund } } ( Ok ( Some ( WasmResult :: Reply ( payload ) ) ) , Responded :: No , OutstandingCalls :: No ) => { let refund = context . available_cycles ; self . call_contexts . remove ( & call_context_id ) ; CallContextAction :: Reply { payload , refund } } ( Ok ( Some ( WasmResult :: Reply ( payload ) ) ) , Responded :: No , OutstandingCalls :: Yes ) => { context . responded = true ; CallContextAction :: Reply { payload , refund : context . available_cycles , } } ( Ok ( Some ( WasmResult :: Reject ( payload ) ) ) , Responded :: No , OutstandingCalls :: No ) => { let refund = context . available_cycles ; self . call_contexts . remove ( & call_context_id ) ; CallContextAction :: Reject { payload , refund } } ( Ok ( Some ( WasmResult :: Reject ( payload ) ) ) , Responded :: No , OutstandingCalls :: Yes ) => { context . responded = true ; CallContextAction :: Reject { payload , refund : context . available_cycles , } } ( Err ( error ) , Responded :: No , OutstandingCalls :: No ) => { let refund = context . available_cycles ; self . call_contexts . remove ( & call_context_id ) ; CallContextAction :: Fail { error , refund } } // The following can never happen since we handle at the SystemApi level if a canister // tries to reply to an already responded call context. ( Ok ( Some ( WasmResult :: Reply ( _ ) ) ) , Responded :: Yes , _ ) => unreachable ! ( " " call_context_id ) , ( Ok ( Some ( WasmResult :: Reject ( _ ) ) ) , Responded :: Yes , _ ) => unreachable ! ( " " call_context_id ) , } }
Accepts a canister result and produces an action that should be taken
by the caller.
Accepts a canister result and produces an action that should be taken by the caller .
&mut self
call_context_id
CallContextId
result
Result<Option<WasmResult>, HypervisorError>
&mut self
call_context_id
CallContextId
result
Result<Option<WasmResult>, HypervisorError>