Skip to main content

Resolver

Struct Resolver 

Source
pub struct Resolver;
Expand description

Walks layered overrides and emits a fresh ResolvedOptions.

The resolver is stateless – it’s just an algorithm. Callers typically own the cache and ask the resolver to refill it via Self::resolve_into.

Implementations§

Source§

impl Resolver

Source

pub fn new() -> Self

The resolver. Zero-sized; equivalent to Resolver::default().

Source

pub fn resolve_into<'a, L>(&self, layers: L, out: &mut ResolvedOptions)
where L: IntoIterator<Item = &'a OptionOverrideSet>,

Walk layers (highest priority first) and write resolved values into out. Each layer is an iterable of OptionOverrides in the layer’s own internal order. Within a layer, last-pushed wins for the same option type; across layers, higher priority wins.

Existing entries in out are preserved unless overridden by a layer; this lets callers seed out with defaults (via the registry’s default-bootstrap, M.2.0b) and have the resolver overlay only what changed.

OverridePriority::High wins regardless of layer position; Low only wins when no Normal/High covers the option. The one thing High does NOT beat is a user’s own per-buffer value — but that needs origins, so it applies only through Self::resolve_into_with_origins with a layer tagged OptionOrigin::BufferLocal. Within a single layer, two overrides at the same priority resolve to last-pushed (per mode-architecture.md §6.2 conflict policy; M.2.1 hooks this to a ModeEvent::OptionConflict emission).

Origin is not tracked (every winner is recorded as OptionOrigin::GlobalConfig); use Self::resolve_into_with_origins when :set name? / :setlocal name? echo is needed.

§Examples
use std::any::TypeId;
use lattice_config::{
    OptionOverride, OptionOverrideSet, OverridePriority, ResolvedOptions, Resolver,
    Tabstop, Wrap,
};

// Seed with the "global" values, as the registry bootstrap would.
let mut out = ResolvedOptions::new();
out.insert::<Tabstop>(8);
out.insert::<Wrap>(true);

// Highest-priority layer first: a minor mode, then a major mode.
let minor: OptionOverrideSet =
    [OptionOverride::new(TypeId::of::<Tabstop>(), 2_i64)].into_iter().collect();
let major: OptionOverrideSet = [
    OptionOverride::new(TypeId::of::<Tabstop>(), 4_i64),
    OptionOverride::with_priority(TypeId::of::<Wrap>(), false, OverridePriority::High),
]
.into_iter()
.collect();

Resolver::new().resolve_into([&minor, &major], &mut out);
assert_eq!(*out.get::<Tabstop>().unwrap(), 2); // higher layer wins among Normals
assert_eq!(*out.get::<Wrap>().unwrap(), false); // High wins from a lower layer
Source

pub fn resolve_into_with_origins<'a>( &self, layers: impl IntoIterator<Item = (&'a OptionOverrideSet, OptionOrigin)>, out: &mut ResolvedOptions, )

Origin-aware resolution. Each element is an (&OptionOverrideSet, OptionOrigin) pair; the origin is recorded alongside the winning value in out. The caller is responsible for assigning the correct OptionOrigin to each layer (e.g. BufferLocal for the buffer-local override set, ModeContribution { mode_id } for each mode’s set).

§Examples

A :setlocal value beats a mode’s High contribution:

use std::any::TypeId;
use lattice_config::{
    OptionOrigin, OptionOverride, OptionOverrideSet, OverridePriority, ResolvedOptions,
    Resolver, Tabstop,
};

let local: OptionOverrideSet =
    [OptionOverride::new(TypeId::of::<Tabstop>(), 3_i64)].into_iter().collect();
let mode: OptionOverrideSet = [OptionOverride::with_priority(
    TypeId::of::<Tabstop>(),
    8_i64,
    OverridePriority::High,
)]
.into_iter()
.collect();

let mut out = ResolvedOptions::new();
Resolver::new().resolve_into_with_origins(
    [
        (&local, OptionOrigin::BufferLocal),
        (&mode, OptionOrigin::ModeContribution { mode_id: "rust-mode".into() }),
    ],
    &mut out,
);
assert_eq!(*out.get::<Tabstop>().unwrap(), 3);
assert_eq!(out.get_origin::<Tabstop>(), OptionOrigin::BufferLocal);
assert_eq!(out.get_origin::<Tabstop>().to_string(), "buffer-local");

Trait Implementations§

Source§

impl Default for Resolver

Source§

fn default() -> Resolver

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more