public IReservationsProgram <int?> TryAccept(Reservation reservation) { return(ReservationsProgram .IsReservationInFuture(reservation) .SelectMany(isInFuture => { if (!isInFuture) { return new Pure <int?>(null); } return ReservationsProgram .ReadReservations(reservation.Date) .SelectMany(reservations => { var reservedSeats = reservations.Sum(r => r.Quantity); if (Capacity < reservedSeats + reservation.Quantity) { return new Pure <int?>(null); } reservation.IsAccepted = true; return ReservationsProgram .Create(reservation) .Select(x => new int?(x)); }); })); }
public static async Task <TResult> Run <TResult>(this ReservationsProgram <TResult> prg, IReservationsInstrHandler handler) { var result = default(TResult); var done = false; while (!done) { switch (prg) { case Return <TResult> ret: result = ret.Result; done = true; break; case Delay <TResult> delay: prg = delay.Func(); break; case Await <TResult> _await: prg = await _await.Accept(handler); break; default: throw new NotSupportedException($"{prg.GetType().Name}"); } } return(result); }
public void Start <TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine { var state = stateMachine; this.cont = () => { state.MoveNext(); return(this.prg); }; this.prg = new Delay <TResult>(cont); }
public IReservationsProgram <IMaybe <int> > TryAccept(Reservation reservation) { return (from isInFuture in ReservationsProgram.IsReservationInFuture(reservation) from _ in ReservationsProgram.Guard(isInFuture) from reservations in ReservationsProgram.ReadReservations(reservation.Date) let reservedSeats = reservations.Sum(r => r.Quantity) from __ in ReservationsProgram.Guard(reservedSeats + reservation.Quantity <= Capacity) from ___ in ReservationsProgram.Do(() => { reservation.IsAccepted = true; }) from id in ReservationsProgram.Create(reservation) select id); }
public void AwaitUnsafeOnCompleted <TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : ReservationsInstr where TStateMachine : IAsyncStateMachine { this.prg = awaiter.Await(this.cont); }
public void SetResult(TResult result) { this.prg = new Return <TResult>(result); }