---
source: framec/tests/rust_snapshots.rs
expression: "compile_fixture(\"12_no_persist\", \"rust\")"
---
#[allow(dead_code)]
#[allow(non_camel_case_types)]
#[allow(non_snake_case)]
#[allow(unused_variables)]
#[allow(unused_mut)]
#[allow(unused_imports)]
#[allow(clippy::assign_op_pattern)]
#[allow(clippy::clone_on_copy)]
#[allow(clippy::derivable_impls)]
#[allow(clippy::match_single_binding)]
#[allow(clippy::needless_return)]
#[allow(clippy::new_without_default)]
#[allow(clippy::single_match)]
mod _no_persist_framec {
    use super::*;
    extern crate alloc;
    use alloc::{vec, format};
    #[derive(Clone, Debug)]
    #[allow(dead_code, non_camel_case_types)]
    enum NoPersistFrameEvent {
        Bump {  },
        SetCache { v: i32 },
        GetCount {  },
        GetCache {  },
        FrameEnter { args: Vec<String> },
        FrameExit { args: Vec<String> },
    }

    #[derive(Clone)]
    #[allow(dead_code, non_camel_case_types)]
    enum NoPersistFrameReturn {
        GetCache(i32),
        GetCount(i32),
        _Lifecycle(alloc::rc::Rc<dyn core::any::Any>),
    }

    #[allow(dead_code)]
    impl NoPersistFrameEvent {
        fn name(&self) -> &'static str {
            match self {
                NoPersistFrameEvent::Bump { .. } => "bump",
                NoPersistFrameEvent::SetCache { .. } => "set_cache",
                NoPersistFrameEvent::GetCount { .. } => "get_count",
                NoPersistFrameEvent::GetCache { .. } => "get_cache",
                NoPersistFrameEvent::FrameEnter { .. } => "$>",
                NoPersistFrameEvent::FrameExit { .. } => "<$",
            }
        }
    }

    #[derive(Clone, Debug)]
    #[allow(dead_code, non_camel_case_types)]
    enum NoPersistFrameValue {
        Int(i64),
        Float(f64),
        Bool(bool),
        Str(String),
        List(Vec<Self>),
        Dict(alloc::collections::BTreeMap<String, Self>),
    }

    #[allow(dead_code, non_camel_case_types)]
    struct NoPersistFrameContext {
        event: alloc::rc::Rc<NoPersistFrameEvent>,
        _return: Option<NoPersistFrameReturn>,
        _data: alloc::collections::BTreeMap<String, NoPersistFrameValue>,
        _transitioned: bool,
    }

    impl NoPersistFrameContext {
        fn new(event: alloc::rc::Rc<NoPersistFrameEvent>, default_return: Option<NoPersistFrameReturn>) -> Self {
            Self {
                event,
                _return: default_return,
                _data: alloc::collections::BTreeMap::new(),
                _transitioned: false,
            }
        }
    }

    #[allow(dead_code, non_camel_case_types)]
    #[derive(Clone)]
    enum NoPersistStateContext {
        Active,
        Empty,
    }

    impl Default for NoPersistStateContext {
        fn default() -> Self {
            NoPersistStateContext::Active
        }
    }

    #[allow(dead_code, non_camel_case_types)]
    #[derive(Clone)]
    struct NoPersistCompartment {
        state: String,
        state_context: NoPersistStateContext,
        enter_args: Vec<String>,
        exit_args: Vec<String>,
        forward_event: Option<NoPersistFrameEvent>,
        parent_compartment: Option<Box<NoPersistCompartment>>,
    }

    impl NoPersistCompartment {
        fn new(state: &str) -> Self {
            let state_context = match state {
                "Active" => NoPersistStateContext::Active,
                _ => NoPersistStateContext::Empty,
            };
            Self {
                state: state.to_string(),
                state_context,
                enter_args: Vec::new(),
                exit_args: Vec::new(),
                forward_event: None,
                parent_compartment: None,
            }
        }
    }

    #[allow(dead_code)]
    pub struct NoPersist {
        _state_stack: Vec<NoPersistCompartment>,
        __compartment: NoPersistCompartment,
        __next_compartment: Option<NoPersistCompartment>,
        _context_stack: Vec<NoPersistFrameContext>,
        pub count: i32,
        pub cache: i32,
    }

    #[allow(non_snake_case)]
    impl NoPersist {
        pub fn new() -> Self {
            Self {
                _state_stack: Vec::new(),
                _context_stack: Vec::new(),
                count: 0,
                cache: -1,
                __compartment: NoPersistCompartment::new("Active"),
                __next_compartment: None,
            }
        }

        pub fn __create() -> Self {
            let mut c = Self::new();
            c.__compartment = c.__prepareEnter("Active", vec![]);
            let __e = alloc::rc::Rc::new(NoPersistFrameEvent::FrameEnter { args: c.__compartment.enter_args.clone() });
            let __ctx = NoPersistFrameContext::new(alloc::rc::Rc::clone(&__e), None);
            c._context_stack.push(__ctx);
            c.__kernel(&__e);
            c._context_stack.pop();
            c
        }

        fn __hsm_chain(&mut self, leaf: &str) -> &'static [&'static str] {
            match leaf {
                "Active" => &["Active"],
                _ => &[],
            }
        }

        fn __prepareEnter(&mut self, leaf: &str, enter_args: Vec<String>) -> NoPersistCompartment {
            let chain = self.__hsm_chain(leaf);
            let mut comp: Option<NoPersistCompartment> = None;
            for name in chain.iter() {
                let mut new_comp = NoPersistCompartment::new(name);
                new_comp.enter_args = enter_args.clone();
                if let Some(parent) = comp.take() {
                    new_comp.parent_compartment = Some(Box::new(parent));
                }
                comp = Some(new_comp);
            }
            comp.expect("chain must contain at least the leaf state")
        }

        fn __prepareExit(&mut self, exit_args: Vec<String>) {
            self.__compartment.exit_args = exit_args.clone();
            let mut cursor = self.__compartment.parent_compartment.as_deref_mut();
            while let Some(c) = cursor {
                c.exit_args = exit_args.clone();
                cursor = c.parent_compartment.as_deref_mut();
            }
        }

        fn __kernel(&mut self, __e: &alloc::rc::Rc<NoPersistFrameEvent>) {
            // Route event to current state.
            self.__router(__e);
            // Drain any transitions queued by the handler.
            while self.__next_compartment.is_some() {
                let next_compartment = self.__next_compartment.take().expect("invariant: while-loop guard checked is_some()");
                // Exit the current (leaf) state.
                let exit_args = self.__compartment.exit_args.clone();
                let exit_event = alloc::rc::Rc::new(NoPersistFrameEvent::FrameExit { args: exit_args });
                self.__router(&exit_event);
                // Switch to the new compartment.
                self.__compartment = next_compartment;
                // Three-branch forward-event handling (RFC-0025 Track B.1: forward
                // event is matched on enum variant; $> recognition is now a
                // structural match, not a string compare).
                match self.__compartment.forward_event.take() {
                    None => {
                        // No forwarded event — synthesize a fresh $>.
                        let enter_args = self.__compartment.enter_args.clone();
                        let enter_event = alloc::rc::Rc::new(NoPersistFrameEvent::FrameEnter { args: enter_args });
                        self.__router(&enter_event);
                    }
                    Some(fwd) if matches!(fwd, NoPersistFrameEvent::FrameEnter { .. }) => {
                        // Forwarded event IS $> — dispatch directly so the
                        // destination's $> handler receives the caller's payload.
                        let fwd_rc = alloc::rc::Rc::new(fwd);
                        self.__router(&fwd_rc);
                    }
                    Some(fwd) => {
                        // Forwarded event is not $> — initialize the destination
                        // with a fresh $>, then dispatch the forward.
                        let enter_args = self.__compartment.enter_args.clone();
                        let enter_event = alloc::rc::Rc::new(NoPersistFrameEvent::FrameEnter { args: enter_args });
                        self.__router(&enter_event);
                        let fwd_rc = alloc::rc::Rc::new(fwd);
                        self.__router(&fwd_rc);
                    }
                }
                for ctx in self._context_stack.iter_mut() {
                    ctx._transitioned = true;
                }
            }
        }

        fn __router(&mut self, __e: &alloc::rc::Rc<NoPersistFrameEvent>) {
            let __ev: &NoPersistFrameEvent = __e;
            match self.__compartment.state.as_str() {
                "Active" => self._state_Active(__ev),
                _ => {}
            }
        }

        fn __transition(&mut self, next_compartment: NoPersistCompartment) {
            self.__next_compartment = Some(next_compartment);
        }

        pub fn bump(&mut self) {
            let __e = alloc::rc::Rc::new(NoPersistFrameEvent::Bump {});
            let mut __ctx = NoPersistFrameContext::new(alloc::rc::Rc::clone(&__e), None);
            self._context_stack.push(__ctx);
            self.__kernel(&__e);
            self._context_stack.pop();
        }

        pub fn set_cache(&mut self, v: i32) {
            let __e = alloc::rc::Rc::new(NoPersistFrameEvent::SetCache { v: v.clone() });
            let mut __ctx = NoPersistFrameContext::new(alloc::rc::Rc::clone(&__e), None);
            self._context_stack.push(__ctx);
            self.__kernel(&__e);
            self._context_stack.pop();
        }

        pub fn get_count(&mut self) -> i32 {
            let __e = alloc::rc::Rc::new(NoPersistFrameEvent::GetCount {});
            let mut __ctx = NoPersistFrameContext::new(alloc::rc::Rc::clone(&__e), None);
            self._context_stack.push(__ctx);
            self.__kernel(&__e);
            let __ctx = self._context_stack.pop().expect("invariant: handler must have pushed a context before reading return");
            match __ctx._return {
                Some(NoPersistFrameReturn::GetCount(v)) => v,
                Some(NoPersistFrameReturn::_Lifecycle(v)) => v.downcast_ref::<i32>().cloned().unwrap_or_default(),
                _ => Default::default(),
            }
        }

        pub fn get_cache(&mut self) -> i32 {
            let __e = alloc::rc::Rc::new(NoPersistFrameEvent::GetCache {});
            let mut __ctx = NoPersistFrameContext::new(alloc::rc::Rc::clone(&__e), None);
            self._context_stack.push(__ctx);
            self.__kernel(&__e);
            let __ctx = self._context_stack.pop().expect("invariant: handler must have pushed a context before reading return");
            match __ctx._return {
                Some(NoPersistFrameReturn::GetCache(v)) => v,
                Some(NoPersistFrameReturn::_Lifecycle(v)) => v.downcast_ref::<i32>().cloned().unwrap_or_default(),
                _ => Default::default(),
            }
        }

        fn _state_Active(&mut self, __e: &NoPersistFrameEvent) {
            match __e {
                NoPersistFrameEvent::Bump { .. } => { self._s_Active_hdl_user_bump(__e); }
                NoPersistFrameEvent::GetCache { .. } => { self._s_Active_hdl_user_get_cache(__e); }
                NoPersistFrameEvent::GetCount { .. } => { self._s_Active_hdl_user_get_count(__e); }
                NoPersistFrameEvent::SetCache { v, .. } => {
                    self._s_Active_hdl_user_set_cache(__e, *v);
                }
                _ => {}
            }
        }

        fn _s_Active_hdl_user_bump(&mut self, __e: &NoPersistFrameEvent) {
            self.count = self.count + 1;
        }

        fn _s_Active_hdl_user_get_cache(&mut self, __e: &NoPersistFrameEvent) {
            let __return_val = NoPersistFrameReturn::GetCache(self.cache);
             if let Some(ctx) = self._context_stack.last_mut() { ctx._return = Some(__return_val); }
        }

        fn _s_Active_hdl_user_get_count(&mut self, __e: &NoPersistFrameEvent) {
            let __return_val = NoPersistFrameReturn::GetCount(self.count);
             if let Some(ctx) = self._context_stack.last_mut() { ctx._return = Some(__return_val); }
        }

        fn _s_Active_hdl_user_set_cache(&mut self, __e: &NoPersistFrameEvent, v: i32) {
            self.cache = v;
        }

        pub fn snapshot(&mut self) -> String {
            if !self._context_stack.is_empty() { panic!("E700: system not quiescent"); }
            fn serialize_state_context(ctx: &NoPersistStateContext) -> serde_json::Value {
                match ctx {
                    NoPersistStateContext::Active => serde_json::json!({}),
                    NoPersistStateContext::Empty => serde_json::json!({}),
                }
            }
            fn serialize_comp(comp: &NoPersistCompartment) -> serde_json::Value {
                let parent = match &comp.parent_compartment {
                    Some(p) => serialize_comp(p),
                    None => serde_json::Value::Null,
                };
                serde_json::json!({
                    "state": comp.state,
                    "state_context": serialize_state_context(&comp.state_context),
                    "parent_compartment": parent,
                })
            }
            let compartment_data = serialize_comp(&self.__compartment);
            let stack_data: Vec<serde_json::Value> = self._state_stack.iter()
                .map(|comp| serialize_comp(comp))
                .collect();
            serde_json::json!({
                "_compartment": compartment_data,
                "_state_stack": stack_data,
                "count": self.count,
            }).to_string()
        }

        pub fn restore(&mut self, json: String) {
            let __json_str: &str = &json;
            let data: serde_json::Value = serde_json::from_str(__json_str).expect("E950: persist load — input is not valid JSON");
            fn deserialize_state_context(state: &str, data: &serde_json::Value) -> NoPersistStateContext {
                match state {
                    "Active" => NoPersistStateContext::Active,
                    _ => NoPersistStateContext::Empty,
                }
            }
            fn deserialize_comp(data: &serde_json::Value) -> NoPersistCompartment {
                let state = data["state"].as_str().expect("E951: persist load — compartment missing string \"state\" field");
                let mut comp = NoPersistCompartment::new(state);
                let ctx_data = &data["state_context"];
                if !ctx_data.is_null() {
                    comp.state_context = deserialize_state_context(state, ctx_data);
                }
                if !data["parent_compartment"].is_null() {
                    comp.parent_compartment = Some(Box::new(deserialize_comp(&data["parent_compartment"])));
                }
                comp
            }
            let stack: Vec<NoPersistCompartment> = data["_state_stack"].as_array()
                .map(|arr| arr.iter()
                    .map(|v| deserialize_comp(v))
                    .collect())
                .unwrap_or_default();
            let compartment = deserialize_comp(&data["_compartment"]);
            self._state_stack = stack;
            self._context_stack = vec![];
            self.__compartment = compartment;
            self.__next_compartment = None;
            self.count = serde_json::from_value(data["count"].clone()).unwrap_or_else(|e| panic!("E952: persist load — field count failed to deserialize: {}", e));
        }
    }
}
pub use _no_persist_framec::*;
