IncrementalSolver

Struct IncrementalSolver 

Source
pub struct IncrementalSolver<'a> { /* private fields */ }
Expand description

Incremental constraint solver for streaming deserialization.

Unlike batch solving where all field names are known upfront, this solver processes fields one at a time as they arrive. It minimizes deferred fields by immediately setting fields that have the same path in all remaining candidate configurations.

§Example

use facet::Facet;
use facet_solver::{Schema, IncrementalSolver, FieldDecision};

#[derive(Facet)]
struct SimpleConfig { port: u16 }

#[derive(Facet)]
struct AdvancedConfig { host: String, port: u16 }

#[derive(Facet)]
#[repr(u8)]
enum Config {
    Simple(SimpleConfig),
    Advanced(AdvancedConfig),
}

#[derive(Facet)]
struct Server {
    name: String,
    #[facet(flatten)]
    config: Config,
}

let schema = Schema::build(Server::SHAPE).unwrap();
let mut solver = IncrementalSolver::new(&schema);

// "name" exists in all configs at the same path - set directly
assert!(matches!(solver.see_key("name"), FieldDecision::SetDirectly(_)));

// "host" only exists in Advanced - disambiguates!
match solver.see_key("host") {
    FieldDecision::Disambiguated { config, current_field } => {
        assert_eq!(current_field.serialized_name, "host");
        assert!(config.field("port").is_some()); // Advanced has port too
    }
    _ => panic!("expected disambiguation"),
}

Implementations§

Source§

impl<'a> IncrementalSolver<'a>

Source

pub fn new(schema: &'a Schema) -> Self

Create a new incremental solver from a schema.

Source

pub fn candidates(&self) -> Vec<&'a Configuration>

Get the current candidate configurations.

Source

pub fn see_key(&mut self, key: &'a str) -> FieldDecision<'a>

Process a field key. Returns what to do with the value.

Source

pub fn deferred_keys(&self) -> &[&'a str]

Get the keys that have been deferred.

Source

pub fn clear_deferred(&mut self)

Clear the deferred keys (call after replaying).

Source

pub fn finish( self, seen_keys: &BTreeSet<&str>, ) -> Result<&'a Configuration, SolverError>

Finish solving. Returns error if still ambiguous or missing required fields.

When multiple candidates remain, this filters out any that are missing required fields. This handles the case where one variant’s fields are a subset of another’s (e.g., Http { url } vs Git { url, branch }). If input only contains url, both match the “has this field” check, but Git is filtered out because it’s missing required branch.

Trait Implementations§

Source§

impl<'a> Debug for IncrementalSolver<'a>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a> Freeze for IncrementalSolver<'a>

§

impl<'a> RefUnwindSafe for IncrementalSolver<'a>

§

impl<'a> Send for IncrementalSolver<'a>

§

impl<'a> Sync for IncrementalSolver<'a>

§

impl<'a> Unpin for IncrementalSolver<'a>

§

impl<'a> UnwindSafe for IncrementalSolver<'a>

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.

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.