fn resolve(
    focused: Entity,
    request: NavRequest,
    queries: &NavQueries,
    from: Vec<Entity>,
) -> NavEvent {
    use NavRequest::*;

    assert!(
        queries.focusables.get(focused).is_ok(),
        "The resolution algorithm MUST go from a focusable element"
    );
    assert!(
        !from.contains(&focused),
        "Navigation graph cycle detected! This panic has prevented a stack overflow, \
        please check usages of `NavMenu::reachable_from`"
    );

    let mut from = (from, focused).into();

    macro_rules! or_none {
        ($to_match:expr) => {
            match $to_match {
                Some(x) => x,
                None => return NavEvent::NoChanges { from, request },
            }
        };
    }
    match request {
        Move(direction) => {
            let (parent, cycles) = match parent_menu(focused, queries) {
                Some(val) if !val.1.setting.is_2d() => {
                    return NavEvent::NoChanges { from, request }
                }
                Some(val) => (Some(val.0), val.1.setting.cycles()),
                None => (None, true),
            };
            let siblings = match parent {
                Some(parent) => children_focusables(parent, queries),
                None if !queries.focusables.is_empty() => {
                    let focusables: Vec<_> = queries.focusables.iter().map(|tpl| tpl.0).collect();
                    NonEmpty::try_from(focusables).unwrap()
                }
                None => {
                    panic!("There must be at least one `Focusable` when sending a `NavRequest`!")
                }
            };
            let to = resolve_2d(focused, direction, cycles, &siblings, &queries.transform);
            let to = or_none!(to);
            NavEvent::focus_changed(*to, from)
        }
        Cancel => {
            let to = or_none!(parent_menu(focused, queries));
            let to = or_none!(to.1.focus_parent);
            from.push(to);
            NavEvent::focus_changed(to, from)
        }
        Action => {
            if let Ok((_, focusable)) = queries.focusables.get(focused) {
                if focusable.cancel {
                    let mut from = from.to_vec();
                    from.truncate(from.len() - 1);
                    return resolve(focused, NavRequest::Cancel, queries, from);
                }
            }
            let child_menu = child_menu(focused, queries);
            let (child_menu, menu) = or_none!(child_menu);
            let to = menu.non_inert_child().unwrap_or_else(|| {
                let ret = children_focusables(child_menu, queries);
                *non_inert_within(&ret, queries)
            });
            let to = (to, from.clone().into()).into();
            NavEvent::FocusChanged { to, from }
        }
        ScopeMove(scope_dir) => {
            let (parent, menu) = or_none!(parent_menu(focused, queries));
            let siblings = children_focusables(parent, queries);
            if !menu.setting.is_scope() {
                let focused = or_none!(menu.focus_parent);
                resolve(focused, request, queries, from.into())
            } else {
                let cycles = menu.setting.cycles();
                let to = or_none!(resolve_scope(focused, scope_dir, cycles, &siblings));
                let extra = match child_menu(*to, queries) {
                    Some((_, menu)) => focus_deep(menu.clone(), queries),
                    None => Vec::new(),
                };
                let to = (extra, *to).into();
                NavEvent::FocusChanged { to, from }
            }
        }
        FocusOn(new_to_focus) => {
            let mut from = root_path(focused, queries);
            let mut to = root_path(new_to_focus, queries);
            trim_common_tail(&mut from, &mut to);
            if from == to {
                NavEvent::NoChanges { from, request }
            } else {
                NavEvent::FocusChanged { from, to }
            }
        }
    }
}
/// Resolve `request` where the focused element is `focused`
Resolve `request` where the focused element is `focused`
Resolve ` request ` where the focused element is ` focused `
fn resolve(
    focused: Entity,
    request: NavRequest,
    queries: &NavQueries,
    from: Vec<Entity>,
) -> NavEvent {
    use NavRequest::*;
    assert!(
        queries.focusables.get(focused).is_ok(),
        "The resolution algorithm MUST go from a focusable element"
    );
    assert!(
        !from.contains(&focused),
        "Navigation graph cycle detected! This panic has prevented a stack overflow, \
        please check usages of `NavMenu::reachable_from`"
    );
    let mut from = (from, focused).into();
    macro_rules! or_none {
        ($to_match:expr) => {
            match $to_match {
                Some(x) => x,
                None => return NavEvent::NoChanges { from, request },
            }
        };
    }
    match request {
        Move(direction) => {
            let (parent, cycles) = match parent_menu(focused, queries) {
                Some(val) if !val.1.setting.is_2d() => {
                    return NavEvent::NoChanges { from, request }
                }
                Some(val) => (Some(val.0), val.1.setting.cycles()),
                None => (None, true),
            };
            let siblings = match parent {
                Some(parent) => children_focusables(parent, queries),
                None if !queries.focusables.is_empty() => {
                    let focusables: Vec<_> = queries.focusables.iter().map(|tpl| tpl.0).collect();
                    NonEmpty::try_from(focusables).unwrap()
                }
                None => {
                    panic!("There must be at least one `Focusable` when sending a `NavRequest`!")
                }
            };
            let to = resolve_2d(focused, direction, cycles, &siblings, &queries.transform);
            let to = or_none!(to);
            NavEvent::focus_changed(*to, from)
        }
        Cancel => {
            let to = or_none!(parent_menu(focused, queries));
            let to = or_none!(to.1.focus_parent);
            from.push(to);
            NavEvent::focus_changed(to, from)
        }
        Action => {
            if let Ok((_, focusable)) = queries.focusables.get(focused) {
                if focusable.cancel {
                    let mut from = from.to_vec();
                    from.truncate(from.len() - 1);
                    return resolve(focused, NavRequest::Cancel, queries, from);
                }
            }
            let child_menu = child_menu(focused, queries);
            let (child_menu, menu) = or_none!(child_menu);
            let to = menu.non_inert_child().unwrap_or_else(|| {
                let ret = children_focusables(child_menu, queries);
                *non_inert_within(&ret, queries)
            });
            let to = (to, from.clone().into()).into();
            NavEvent::FocusChanged { to, from }
        }
        ScopeMove(scope_dir) => {
            let (parent, menu) = or_none!(parent_menu(focused, queries));
            let siblings = children_focusables(parent, queries);
            if !menu.setting.is_scope() {
                let focused = or_none!(menu.focus_parent);
                resolve(focused, request, queries, from.into())
            } else {
                let cycles = menu.setting.cycles();
                let to = or_none!(resolve_scope(focused, scope_dir, cycles, &siblings));
                let extra = match child_menu(*to, queries) {
                    Some((_, menu)) => focus_deep(menu.clone(), queries),
                    None => Vec::new(),
                };
                let to = (extra, *to).into();
                NavEvent::FocusChanged { to, from }
            }
        }
        FocusOn(new_to_focus) => {
            let mut from = root_path(focused, queries);
            let mut to = root_path(new_to_focus, queries);
            trim_common_tail(&mut from, &mut to);
            if from == to {
                NavEvent::NoChanges { from, request }
            } else {
                NavEvent::FocusChanged { from, to }
            }
        }
    }
}
fn resolve ( focused : Entity , request : NavRequest , queries : & NavQueries , from : Vec < Entity > , ) -> NavEvent { use NavRequest :: * ; assert ! ( queries focusables get ( focused ) is_ok ( ) " " ) ; assert ! ( from contains ( focused ) " \
 " ) ; let mut from = ( from , focused ) . into ( ) ; macro_rules! or_none { ( $to_match : expr ) => { match $to_match { Some ( x ) x None return NavEvent NoChanges { from request } } } ; } match request { Move ( direction ) => { let ( parent , cycles ) = match parent_menu ( focused , queries ) { Some ( val ) if ! val . 1 . setting . is_2d ( ) => { return NavEvent :: NoChanges { from , request } } Some ( val ) => ( Some ( val . 0 ) , val . 1 . setting . cycles ( ) ) , None => ( None , true ) , } ; let siblings = match parent { Some ( parent ) => children_focusables ( parent , queries ) , None if ! queries . focusables . is_empty ( ) => { let focusables : Vec < _ > = queries . focusables . iter ( ) . map ( | tpl | tpl . 0 ) . collect ( ) ; NonEmpty :: try_from ( focusables ) . unwrap ( ) } None => { panic ! ( " " ) } } ; let to = resolve_2d ( focused , direction , cycles , & siblings , & queries . transform ) ; let to = or_none ! ( to ) ; NavEvent :: focus_changed ( * to , from ) } Cancel => { let to = or_none ! ( parent_menu ( focused queries ) ) ; let to = or_none ! ( to 1 focus_parent ) ; from . push ( to ) ; NavEvent :: focus_changed ( to , from ) } Action => { if let Ok ( ( _ , focusable ) ) = queries . focusables . get ( focused ) { if focusable . cancel { let mut from = from . to_vec ( ) ; from . truncate ( from . len ( ) - 1 ) ; return resolve ( focused , NavRequest :: Cancel , queries , from ) ; } } let child_menu = child_menu ( focused , queries ) ; let ( child_menu , menu ) = or_none ! ( child_menu ) ; let to = menu . non_inert_child ( ) . unwrap_or_else ( | | { let ret = children_focusables ( child_menu , queries ) ; * non_inert_within ( & ret , queries ) } ) ; let to = ( to , from . clone ( ) . into ( ) ) . into ( ) ; NavEvent :: FocusChanged { to , from } } ScopeMove ( scope_dir ) => { let ( parent , menu ) = or_none ! ( parent_menu ( focused queries ) ) ; let siblings = children_focusables ( parent , queries ) ; if ! menu . setting . is_scope ( ) { let focused = or_none ! ( menu focus_parent ) ; resolve ( focused , request , queries , from . into ( ) ) } else { let cycles = menu . setting . cycles ( ) ; let to = or_none ! ( resolve_scope ( focused scope_dir cycles siblings ) ) ; let extra = match child_menu ( * to , queries ) { Some ( ( _ , menu ) ) => focus_deep ( menu . clone ( ) , queries ) , None => Vec :: new ( ) , } ; let to = ( extra , * to ) . into ( ) ; NavEvent :: FocusChanged { to , from } } } FocusOn ( new_to_focus ) => { let mut from = root_path ( focused , queries ) ; let mut to = root_path ( new_to_focus , queries ) ; trim_common_tail ( & mut from , & mut to ) ; if from == to { NavEvent :: NoChanges { from , request } } else { NavEvent :: FocusChanged { from , to } } } } }
Resolve `request` where the focused element is `focused`
Resolve ` request ` where the focused element is ` focused `
focused
Entity
request
NavRequest
queries
&NavQueries
from
Vec<Entity>
focused
Entity
request
NavRequest
queries
&NavQueries
from
Vec<Entity>