{"id":19914221,"url":"https://github.com/fmeringdal/rust-rrule","last_synced_at":"2025-05-16T07:07:09.342Z","repository":{"id":37496466,"uuid":"304160392","full_name":"fmeringdal/rust-rrule","owner":"fmeringdal","description":"Rust crate for working with recurrence rules for calendar dates as defined in the iCalendar RFC and more.","archived":false,"fork":false,"pushed_at":"2025-04-20T17:53:31.000Z","size":889,"stargazers_count":75,"open_issues_count":21,"forks_count":22,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-04-20T18:02:11.708Z","etag":null,"topics":["calendar","cargo","crate","fmeringdal","icalendar-rfc","library","python-dateutil","recurrence-rules","rfc","rrule","rust"],"latest_commit_sha":null,"homepage":"https://docs.rs/rrule","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fmeringdal.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-10-14T23:36:40.000Z","updated_at":"2025-04-20T17:53:35.000Z","dependencies_parsed_at":"2024-05-19T21:26:16.996Z","dependency_job_id":"7edc09ff-1e2b-44b0-a2b4-62954e1a5c7c","html_url":"https://github.com/fmeringdal/rust-rrule","commit_stats":{"total_commits":356,"total_committers":9,"mean_commits":39.55555555555556,"dds":0.3539325842696629,"last_synced_commit":"8f4411ffd06316ac4bc98b65ceabcdbe06fbd00d"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fmeringdal%2Frust-rrule","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fmeringdal%2Frust-rrule/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fmeringdal%2Frust-rrule/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fmeringdal%2Frust-rrule/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fmeringdal","download_url":"https://codeload.github.com/fmeringdal/rust-rrule/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254485065,"owners_count":22078767,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["calendar","cargo","crate","fmeringdal","icalendar-rfc","library","python-dateutil","recurrence-rules","rfc","rrule","rust"],"created_at":"2024-11-12T21:35:35.194Z","updated_at":"2025-05-16T07:07:04.332Z","avatar_url":"https://github.com/fmeringdal.png","language":"Rust","readme":"\u003ch1 align=\"center\"\u003eRRule.rs\u003c/h1\u003e\n\u003cp align=\"center\"\u003eA pure and efficient Rust implementation of recurrence rules as defined in the iCalendar RFC.\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://codecov.io/gh/fmeringdal/rust-rrule\"\u003e\n    \u003cimg src=\"https://codecov.io/gh/fmeringdal/rust-rrule/branch/main/graph/badge.svg?token=UneXhtuXWo\"/\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://crates.io/crates/rrule\"\u003e\u003cimg src=\"https://img.shields.io/crates/v/rrule.svg\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://docs.rs/rrule/latest/rrule/\"\u003e\u003cimg src=\"https://img.shields.io/badge/docs-rrule-blue\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n## Specification\n\nThis crate follows the [iCalendar (RFC-5545) specification][ical_spec] for the \"Recurrence Rule\".\nThe Recurrence Rule spec corresponds to the `RRule` object in this crate.\nIn addition, it allows for adding the [\"DTSTART\" property][dtstart_property] separated by a newline.\n\nThe crate allows for a \"BYEASTER\" filter. But this is opt-in with the feature flag `\"by-easter\"`.\n\n### RRuleSet\n\n`RRuleSet` allows for a combination for `RRule`s and some other properties.\n\n- List of [RRules](https://icalendar.org/iCalendar-RFC-5545/3-8-5-3-recurrence-rule.html):\n  Allows multiple RRules to be combined. (Union, `A ∪ B`)\n- List of [RDates](https://icalendar.org/iCalendar-RFC-5545/3-8-5-2-recurrence-date-times.html):\n  A list of datetime combinations to always include. (Union, `A ∪ B`)\n- List of [ExRule](https://datatracker.ietf.org/doc/html/rfc2445#section-4.8.5.2) (see note below):\n  Allows of RRules that are removed from the results. (Complement `A \\ B` or `A - B`)\n- List of [ExDate](https://icalendar.org/iCalendar-RFC-5545/3-8-5-1-exception-date-times.html):\n  A list of datetime combinations to always exclude. (Complement `A \\ B` or `A - B`)\n\nNote: \"EXRULE\" was originally part of [RFC 2445](https://datatracker.ietf.org/doc/html/rfc2445#section-4.8.5.2),\n[RFC 5545][ical_spec] obsoletes this specification.\nBut \"EXRULE\" works exactly the same als \"RRULE\" except that it excludes dates. You can enable \"EXRULE\" by enabling the \"exrule\" feature flag which is disabled by default.\n\nIf you notice that the implementation differs from the specifications above, please open an issue.\n\n## Library Usage\n\n```rust\nuse rrule::RRuleSet;\n\n// RRule that starts 2012.02.01 and occurs daily for 3 days.\nlet rrule: RRuleSet = \"DTSTART:20120201T093000Z\\nRRULE:FREQ=DAILY;COUNT=3\".parse().unwrap();\n\n// Set hard limit in case of infinitely recurring rules.\nlet limit = 100;\n// Get all recurrences of the rrule\nlet result = rrule.all(limit);\nassert_eq!(result.dates.len(), 3);\n```\n\nSee more examples at [docs.rs](https://docs.rs/rrule)\n\n## Command Line Tool Usage\n\nInstall the command line tool with:\n\n```bash\ncargo install rrule --features=\"cli-tool\"\n```\n\nThen run it with:\n\n```bash\nrrule \"DTSTART:20120201T093000Z\\nRRULE:FREQ=DAILY;COUNT=3\"\n```\n\n## Security\n\nYou should read the [security docs](https://github.com/fmeringdal/rust-rrule/blob/main/SECURITY.md) if you use arbitrary inputs from users for constructing the recurrence rules.\n\n## Limitation and limits\n\nAll dates are limited to the range or years +/-262_000[^1] because of [Chrono][chrono] limits.\nSee [Chrono's limits for more info](https://github.com/chronotope/chrono#limitations).\n\nSupported timezones are limited to by the timezones that [Chrono-Tz][chrono-tz] supports.\nThis is equivalent to the IANA database.\nSee [Chrono-Tz's limits for more info](https://github.com/chronotope/chrono-tz/#limiting-the-timezone-table-to-zones-of-interest).\n\n### Validation Limits\n\n\u003ca name=\"validation_limits\"\u003e\u003c/a\u003e\nBecause the specifications do give a lot of flexibilities this can be [abused very easily](#Security).\nIn order to prevent most of the abuse we've imposed arbitrary limitation when on the `RRuleSet::all`\nmethod. The validation limits aren't enforced for the `RRuleSet::all_unchecked` method or when\nusing the `Iterator` api directly.\n\nLimitations:\n| Description | Arbitrary Limit | Crate Limit |\n|----------------------------------|-----------------------|-----------------------------|\n| Year range | -10_000..=10_000 | -262_000..=262_000 (Chrono) |\n| Max interval with freq Yearly | 10_000 (10000 years) | 65_535 (u16::MAX) |\n| Max interval with freq Monthly | 1_000 (~83 years) | 65_535 (u16::MAX) |\n| Max interval with freq Weekly | 1_000 (~19 years) | 65_535 (u16::MAX) |\n| Max interval with freq Daily | 10_000 (~27 years) | 65_535 (u16::MAX) |\n| Max interval with freq Hourly | 10_000 (~416 days) | 65_535 (u16::MAX) |\n| Max interval with freq Minutely | 10_000 (~7 days) | 65_535 (u16::MAX) |\n| Max interval with freq Secondly | 50_000 (~13 hours) | 65_535 (u16::MAX) |\n| Iteration limit | 100_000 | 4_294_967_295 (u32::MAX) |\n\nBy default, the \"Arbitrary Limit\" is used. If you instead want to use the \"Crate Limit\".\nMake sure you [understand the risks that come with this](#safety).\n\n## Inspired by\n\n- [python-dateutil library](http://labix.org/python-dateutil/)\n- [rrule.js](https://github.com/jakubroztocil/rrule)\n\n## License\n\nThe code in this project is licensed under the [MIT](LICENSE-MIT) or [Apache 2.0](LICENSE-APACHE) license.\n\nAll contributions to this project will be similarly licensed.\n\n[chrono]: https://github.com/chronotope/chrono\n[chrono-tz]: https://github.com/chronotope/chrono-tz/\n[ical_spec]: https://icalendar.org/iCalendar-RFC-5545/3-3-10-recurrence-rule.html\n[dtstart_property]: https://icalendar.org/iCalendar-RFC-5545/3-8-2-4-date-time-start.html\n\n[^1]: See [validation limits](#validation_limits) sections more info.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffmeringdal%2Frust-rrule","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffmeringdal%2Frust-rrule","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffmeringdal%2Frust-rrule/lists"}