Skip to main content

validate_rebind

Function validate_rebind 

Source
pub fn validate_rebind<'a, A>(
    layers: &[&'a Keymap<A>],
    target: usize,
    proposed: KeyInput,
    reserved: &[KeyInput],
) -> RebindVerdict<'a, A>
Expand description

Validates a proposed rebind of proposed into layer layers[target] without mutating the live keymap or requiring A: Clone or A: PartialEq.

§Semantics

The contract is strict: a reserved chord cannot be the target of a rebind, period. A rebind of the same action onto the same chord is refused just like any other rebind onto a reserved key. This is a deliberate design choice: distinguishing “same action, no-op” from “different action, dangerous” requires A: PartialEq, which this function deliberately avoids; and a true no-op rebind is a UI concern that should be filtered before calling this function.

If you need a more permissive variant (e.g. allowing same-action rebinds), add a sibling function with the relaxed contract rather than changing this one. Relaxing an existing function would be a silent behavioural change for callers who rely on the strict semantics; adding a sibling is additive.

§Virtual overlay

No keymap is cloned. For each reserved key r the function walks the layer slice once:

  • If any layer before target already has a binding for r, that layer would win regardless of what target contains, so adding proposed to target cannot affect r’s resolution — the proposed bind is harmless for that reserved key.
  • Otherwise, if proposed == r (direct steal) or proposed.legacy_form() == CollapsesTo(r) (legacy collapse), the rebind is refused with the appropriate BreakReason.

§Panics

Panics if target >= layers.len(). The caller must guarantee target is a valid index into layers.

§Example

use keymap_core::{Key, KeyInput, Keymap, Modifiers, validate_rebind,
                  RebindVerdict, BreakReason};

let esc = KeyInput::new(Key::Esc, Modifiers::NONE);
let cs  = KeyInput::new(Key::Char('s'), Modifiers::CTRL);

let global: Keymap<&str> = Keymap::new();
let layers = [&global];

// ctrl+s is not reserved — allowed.
let v = validate_rebind(&layers, 0, cs, &[esc]);
assert!(matches!(v, RebindVerdict::Allowed { .. }));

// Trying to bind Esc — refused.
let v = validate_rebind(&layers, 0, esc, &[esc]);
assert!(matches!(v, RebindVerdict::BreaksReserved {
    reason: BreakReason::DirectSteal, ..
}));