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
targetalready has a binding forr, that layer would win regardless of whattargetcontains, so addingproposedtotargetcannot affectr’s resolution — the proposed bind is harmless for that reserved key. - Otherwise, if
proposed == r(direct steal) orproposed.legacy_form() == CollapsesTo(r)(legacy collapse), the rebind is refused with the appropriateBreakReason.
§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, ..
}));