packages feed

aws-eventbridge-cron-0.1.0.1: README.md

# aws-eventbridge-cron

Parse AWS EventBridge cron, rate, and one-time expressions and compute their
future run times.

Status: early preview. Expect small API tweaks before a `1.0.0` release.

## Features

- Single entry point: `AWS.EventBridge.Cron` exports the `CronExprT` type,
  `parseCronText` parser, and `nextRunTimes` scheduler.
- Full support for EventBridge-specific syntax such as `?` wildcards, `L`, `LW`,
  weekday ranges, and nth-weekday modifiers (`2#1`).
- `rate(...)` and `at(...)` expressions share the same API, so callers do not
  need to branch on expression variants.
- Schedule introspection helpers: `scheduleKind` returns a `ScheduleKind`, and
  `isRecurring` distinguishes recurring (`cron`/`rate`) expressions from
  `at(...)` one-time schedules.
- Extensive property-based test suite that mirrors the behaviour documented by
  AWS.

## Installation

```
cabal install aws-eventbridge-cron
```

Or add the package to your component:

```cabal
build-depends:
    aws-eventbridge-cron >= 0.1 && < 0.2
```

## Quick Start

```haskell
import AWS.EventBridge.Cron
import Data.Time (UTCTime(..), fromGregorian)
import Data.Time.LocalTime (TimeOfDay(..), timeOfDayToTime)

base :: UTCTime
base = UTCTime (fromGregorian 2025 11 16) (timeOfDayToTime (TimeOfDay 9 0 0))

example :: Either String [UTCTime]
example = do
  expr <- parseCronText "cron(0/15 9 ? NOV SUN 2025)"
  nextRunTimes expr base 4
-- Right [2025-11-16 09:00:00 UTC, 2025-11-16 09:15:00 UTC, ...]
```

The parser also accepts `rate(...)` and `at(...)` expressions:

```haskell
rateExample :: Either String [UTCTime]
rateExample = do
  expr <- parseCronText "rate(10 minutes)"
  nextRunTimes expr base 3

atExample :: Either String [UTCTime]
atExample = do
  expr <- parseCronText "at(2025-11-16T09:30:00)"
  nextRunTimes expr base 5

-- Introspect the parsed expression without re-parsing downstream.
kindExample :: Either String ScheduleKind
kindExample = scheduleKind <$> parseCronText "rate(5 minutes)"
-- Right RateSchedule

isRecurringExample :: Either String Bool
isRecurringExample = isRecurring <$> parseCronText "at(2025-11-16T09:30:00)"
-- Right False
```

### Error Reporting

Parser and evaluator failures return `Left String` with human-readable error
messages:

```haskell
Left "day-of-month and day-of-week fields must use '?' in exactly one position"
```

The messages mirror the constraints enforced by EventBridge when you create
scheduled rules.

## Design Notes

- `CronExprT` is intentionally opaque. Construct values with `parseCronText` and
  feed them into `nextRunTimes`.
- Scheduling honours the EventBridge rule that exactly one of day-of-month or
  day-of-week must be `?`.
- Results are monotonic, capped at the requested limit, and never fall before
  the supplied base time.

See `test/AWS/EventBridge/CronSpec.hs` for more examples and edge cases.

## Development

```bash
cabal build
cabal test
cabal haddock --open
```

## Contributing

Bug reports, suggestions, and pull requests are welcome. Please open an issue
before large-scale changes so we can keep the API coherent.

## License

Released under the BSD-3-Clause license. See `LICENSE` for details.

## References

- [AWS EventBridge cron expression documentation][aws-docs]

[aws-docs]: https://docs.aws.amazon.com/scheduler/latest/UserGuide/schedule-types.html#cron-based