pub struct ValidationSession<P: SessionPhase = Pending> { /* private fields */ }Expand description
Stateful two-phase validation harness for callers (like the loader) that need to interleave validation with other pipeline steps.
The session’s phase is tracked at the type level via P:
SessionPhase (see the phase module for the marker types and
the rationale). The standard sequence is:
ValidationSession::newreturnsValidationSession<Pending>.run_earlyconsumesPendingand returns(ValidationSession<EarlyDone>, Vec<ValidationError>).- Booking (and the post-booking plugin pass) runs externally on the directive list.
run_lateconsumesEarlyDoneand returns(ValidationSession<LateDone>, Vec<ValidationError>).finalizeconsumesLateDoneand returns the deferred E2003 unused-pad warnings.
Standalone callers that don’t run booking between phases (LSP, FFI, tests) run all four calls back-to-back against the same directive list. The verbosity is intentional: it surfaces the phase split so callers explicitly choose whether to interleave booking between Early and Late.
§Spanned vs. unspanned
Each transition has a _spanned variant
(run_early_spanned,
run_late_spanned)
for &[Spanned<Directive>] input. The spanned variants preserve
source-location info on emitted errors so callers (LSP, loader,
FFI) can render file:line:column diagnostics directly.
§Migration from pre-#1236
Replace:
let mut session = ValidationSession::new(options);
let mut errors = session.run_phase(&directives, Phase::Early, today);
errors.extend(session.run_phase(&directives, Phase::Late, today));
errors.extend(session.finalize());with:
let session = ValidationSession::new(options);
let (session, mut errors) = session.run_early(&directives, today);
let (session, late_errors) = session.run_late(&directives, today);
errors.extend(late_errors);
errors.extend(session.finalize());The compile-time enforcement replaces the pre-#1236 runtime
debug_assert! + release-mode no-op for phase ordering.
§Example
use rustledger_validate::{ValidationOptions, ValidationSession};
use rustledger_core::{Directive, naive_date};
let directives: Vec<Directive> = vec![];
let today = naive_date(2030, 1, 1).unwrap();
let session = ValidationSession::new(ValidationOptions::default());
let (session, mut errors) = session.run_early(&directives, today);
// ... booking runs here; plugins ran BEFORE Early ...
let (session, late_errors) = session.run_late(&directives, today);
errors.extend(late_errors);
errors.extend(session.finalize());Implementations§
Source§impl ValidationSession<Pending>
impl ValidationSession<Pending>
Sourcepub fn new(options: ValidationOptions) -> Self
pub fn new(options: ValidationOptions) -> Self
Sourcepub fn run_early(
self,
directives: &[Directive],
today: NaiveDate,
) -> (ValidationSession<EarlyDone>, Vec<ValidationError>)
pub fn run_early( self, directives: &[Directive], today: NaiveDate, ) -> (ValidationSession<EarlyDone>, Vec<ValidationError>)
Run Phase::Early over a slice of raw Directives.
Early runs account/structural checks that don’t need filled-in
amounts. The session’s internal LedgerState is updated so
run_late sees the
accumulated state (open accounts, commodities, pending pads).
Consumes the session and returns it bound to EarlyDone
alongside the errors collected during the phase. The new phase
marker prevents a second run_early call at compile time.
Sourcepub fn run_early_spanned(
self,
directives: &[Spanned<Directive>],
today: NaiveDate,
) -> (ValidationSession<EarlyDone>, Vec<ValidationError>)
pub fn run_early_spanned( self, directives: &[Spanned<Directive>], today: NaiveDate, ) -> (ValidationSession<EarlyDone>, Vec<ValidationError>)
Variant of run_early for
Spanned<Directive> slices. Preserves source-location info on
emitted errors.
Source§impl ValidationSession<EarlyDone>
impl ValidationSession<EarlyDone>
Sourcepub fn run_late(
self,
directives: &[Directive],
today: NaiveDate,
) -> (ValidationSession<LateDone>, Vec<ValidationError>)
pub fn run_late( self, directives: &[Directive], today: NaiveDate, ) -> (ValidationSession<LateDone>, Vec<ValidationError>)
Run Phase::Late over a slice of raw Directives.
Late runs balance/inventory/currency checks that need
filled-in amounts. Must be called AFTER booking has run on the
directive list (and after the post-booking plugin pass, if any).
Consumes the session and returns it bound to LateDone
alongside the errors collected during the phase. The new phase
marker prevents a second run_late call at compile time.
Sourcepub fn run_late_spanned(
self,
directives: &[Spanned<Directive>],
today: NaiveDate,
) -> (ValidationSession<LateDone>, Vec<ValidationError>)
pub fn run_late_spanned( self, directives: &[Spanned<Directive>], today: NaiveDate, ) -> (ValidationSession<LateDone>, Vec<ValidationError>)
Variant of run_late for
Spanned<Directive> slices. Preserves source-location info on
emitted errors.
Source§impl ValidationSession<LateDone>
impl ValidationSession<LateDone>
Sourcepub fn finalize(self) -> Vec<ValidationError>
pub fn finalize(self) -> Vec<ValidationError>
Flush deferred end-of-validation checks. Currently emits unused pad warnings (E2003). Consumes the session because deferred state is per-session.
Auto Trait Implementations§
impl<P> Freeze for ValidationSession<P>
impl<P> RefUnwindSafe for ValidationSession<P>where
P: RefUnwindSafe,
impl<P> Send for ValidationSession<P>where
P: Send,
impl<P> Sync for ValidationSession<P>where
P: Sync,
impl<P> Unpin for ValidationSession<P>where
P: Unpin,
impl<P> UnsafeUnpin for ValidationSession<P>
impl<P> UnwindSafe for ValidationSession<P>where
P: UnwindSafe,
Blanket Implementations§
Source§impl<T> ArchivePointee for T
impl<T> ArchivePointee for T
Source§type ArchivedMetadata = ()
type ArchivedMetadata = ()
Source§fn pointer_metadata(
_: &<T as ArchivePointee>::ArchivedMetadata,
) -> <T as Pointee>::Metadata
fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> LayoutRaw for T
impl<T> LayoutRaw for T
Source§fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
Source§impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
Source§unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
Source§fn resolve_niched(out: Place<NichedOption<T, N1>>)
fn resolve_niched(out: Place<NichedOption<T, N1>>)
out indicating that a T is niched.