Skip to content

Commit

Permalink
feat: make js depend on own rrule (#172)
Browse files Browse the repository at this point in the history
* feat: make js depend on own rrule

* docs: update readme
  • Loading branch information
lsndr authored Jun 7, 2024
1 parent a0cdcd0 commit 7ff6e79
Show file tree
Hide file tree
Showing 40 changed files with 1,838 additions and 1,842 deletions.
16 changes: 16 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ path = "lib/lib.rs"
chrono = "0.4.24"
chrono-tz = "0.8.5"
indexmap = "2.2.6"
itertools = "0.13.0"
# Default enable napi5 feature, see https://nodejs.org/api/n-api.html#node-api-version-matrix
napi = { version = "2.16.6", default-features = false, features = ["napi5"] }
napi-derive = "2.16.5"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
[![license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/lsndr/rrule-rust/blob/master/LICENSE.md)


`rrule-rust` is a [napi-rs](https://napi.rs) wrapper around Rust's [rrule](https://crates.io/crates/rrule) crate
`rrule-rust` is a library for working with recurrence rules based on Rust's [rrule](https://crates.io/crates/rrule) crate


1. [Quick Start](#quick-start)
Expand Down
1 change: 1 addition & 0 deletions benchmark/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ function suite(tzid: string) {
count: 30,
interval: 1,
});

const set = new node.RRuleSet();
set.rrule(rrule);

Expand Down
21 changes: 6 additions & 15 deletions lib/js.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,6 @@
mod datetime;
mod frequency;
mod month;
mod n_weekday;
mod rrule;
mod rrule_set;
mod weekday;

pub use datetime::DateTime;
pub use frequency::Frequency;
pub use month::Month;
pub use n_weekday::NWeekday;
pub use rrule::RRule;
pub use rrule_set::RRuleSet;
pub use weekday::Weekday;
pub mod frequency;
pub mod month;
pub mod n_weekday;
pub mod rrule;
pub mod rrule_set;
pub mod weekday;
72 changes: 20 additions & 52 deletions lib/js/frequency.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::str::FromStr;

use crate::rrule::frequency;
use napi_derive::napi;

#[napi(js_name = "Frequency")]
Expand All @@ -13,61 +12,30 @@ pub enum Frequency {
Secondly,
}

impl From<rrule::Frequency> for Frequency {
fn from(freq: rrule::Frequency) -> Self {
match freq {
rrule::Frequency::Daily => Frequency::Daily,
rrule::Frequency::Hourly => Frequency::Hourly,
rrule::Frequency::Minutely => Frequency::Minutely,
rrule::Frequency::Monthly => Frequency::Monthly,
rrule::Frequency::Secondly => Frequency::Secondly,
rrule::Frequency::Weekly => Frequency::Weekly,
rrule::Frequency::Yearly => Frequency::Yearly,
}
}
}

impl Into<rrule::Frequency> for Frequency {
fn into(self) -> rrule::Frequency {
impl Into<frequency::Frequency> for Frequency {
fn into(self) -> frequency::Frequency {
match self {
Frequency::Daily => rrule::Frequency::Daily,
Frequency::Hourly => rrule::Frequency::Hourly,
Frequency::Minutely => rrule::Frequency::Minutely,
Frequency::Monthly => rrule::Frequency::Monthly,
Frequency::Secondly => rrule::Frequency::Secondly,
Frequency::Weekly => rrule::Frequency::Weekly,
Frequency::Yearly => rrule::Frequency::Yearly,
Frequency::Yearly => frequency::Frequency::Yearly,
Frequency::Monthly => frequency::Frequency::Monthly,
Frequency::Weekly => frequency::Frequency::Weekly,
Frequency::Daily => frequency::Frequency::Daily,
Frequency::Hourly => frequency::Frequency::Hourly,
Frequency::Minutely => frequency::Frequency::Minutely,
Frequency::Secondly => frequency::Frequency::Secondly,
}
}
}

impl Into<String> for Frequency {
fn into(self) -> String {
match self {
Frequency::Yearly => "YEARLY".to_string(),
Frequency::Monthly => "MONTHLY".to_string(),
Frequency::Weekly => "WEEKLY".to_string(),
Frequency::Daily => "DAILY".to_string(),
Frequency::Hourly => "HOURLY".to_string(),
Frequency::Minutely => "MINUTELY".to_string(),
Frequency::Secondly => "SECONDLY".to_string(),
}
}
}

impl FromStr for Frequency {
type Err = String;

fn from_str(str: &str) -> Result<Self, Self::Err> {
match &*str.to_uppercase() {
"DAILY" => Ok(Frequency::Daily),
"HOURLY" => Ok(Frequency::Hourly),
"MINUTELY" => Ok(Frequency::Minutely),
"MONTHLY" => Ok(Frequency::Monthly),
"SECONDLY" => Ok(Frequency::Secondly),
"WEEKLY" => Ok(Frequency::Weekly),
"YEARLY" => Ok(Frequency::Yearly),
_ => Err(format!("Invalid frequency: {}", str)),
impl From<&frequency::Frequency> for Frequency {
fn from(frequency: &frequency::Frequency) -> Self {
match frequency {
frequency::Frequency::Yearly => Frequency::Yearly,
frequency::Frequency::Monthly => Frequency::Monthly,
frequency::Frequency::Weekly => Frequency::Weekly,
frequency::Frequency::Daily => Frequency::Daily,
frequency::Frequency::Hourly => Frequency::Hourly,
frequency::Frequency::Minutely => Frequency::Minutely,
frequency::Frequency::Secondly => Frequency::Secondly,
}
}
}
101 changes: 29 additions & 72 deletions lib/js/month.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::str::FromStr;

use crate::rrule::month;
use napi_derive::napi;

#[napi(js_name = "Month")]
Expand All @@ -18,82 +17,40 @@ pub enum Month {
December,
}

impl ToString for Month {
fn to_string(&self) -> String {
impl Into<month::Month> for Month {
fn into(self) -> month::Month {
match self {
Month::January => "1".to_string(),
Month::February => "2".to_string(),
Month::March => "3".to_string(),
Month::April => "4".to_string(),
Month::May => "5".to_string(),
Month::June => "6".to_string(),
Month::July => "7".to_string(),
Month::August => "8".to_string(),
Month::September => "9".to_string(),
Month::October => "10".to_string(),
Month::November => "11".to_string(),
Month::December => "12".to_string(),
}
}
}

impl FromStr for Month {
type Err = String;

fn from_str(month: &str) -> Result<Self, Self::Err> {
match month {
"1" => Ok(Month::January),
"2" => Ok(Month::February),
"3" => Ok(Month::March),
"4" => Ok(Month::April),
"5" => Ok(Month::May),
"6" => Ok(Month::June),
"7" => Ok(Month::July),
"8" => Ok(Month::August),
"9" => Ok(Month::September),
"10" => Ok(Month::October),
"11" => Ok(Month::November),
"12" => Ok(Month::December),
_ => Err(format!("Unknown month number: {}", month)),
Month::January => month::Month::January,
Month::February => month::Month::February,
Month::March => month::Month::March,
Month::April => month::Month::April,
Month::May => month::Month::May,
Month::June => month::Month::June,
Month::July => month::Month::July,
Month::August => month::Month::August,
Month::September => month::Month::September,
Month::October => month::Month::October,
Month::November => month::Month::November,
Month::December => month::Month::December,
}
}
}

impl From<&u8> for Month {
fn from(month: &u8) -> Self {
impl From<&month::Month> for Month {
fn from(month: &month::Month) -> Self {
match month {
1 => Month::January,
2 => Month::February,
3 => Month::March,
4 => Month::April,
5 => Month::May,
6 => Month::June,
7 => Month::July,
8 => Month::August,
9 => Month::September,
10 => Month::October,
11 => Month::November,
12 => Month::December,
_ => panic!("Unknown month index: {}", month),
}
}
}

impl Into<chrono::Month> for Month {
fn into(self) -> chrono::Month {
match self {
Month::January => chrono::Month::January,
Month::February => chrono::Month::February,
Month::March => chrono::Month::March,
Month::April => chrono::Month::April,
Month::May => chrono::Month::May,
Month::June => chrono::Month::June,
Month::July => chrono::Month::July,
Month::August => chrono::Month::August,
Month::September => chrono::Month::September,
Month::October => chrono::Month::October,
Month::November => chrono::Month::November,
Month::December => chrono::Month::December,
month::Month::January => Month::January,
month::Month::February => Month::February,
month::Month::March => Month::March,
month::Month::April => Month::April,
month::Month::May => Month::May,
month::Month::June => Month::June,
month::Month::July => Month::July,
month::Month::August => Month::August,
month::Month::September => Month::September,
month::Month::October => Month::October,
month::Month::November => Month::November,
month::Month::December => Month::December,
}
}
}
90 changes: 11 additions & 79 deletions lib/js/n_weekday.rs
Original file line number Diff line number Diff line change
@@ -1,95 +1,27 @@
use std::str::FromStr;

use super::weekday::Weekday;
use crate::rrule::n_weekday;
use napi_derive::napi;

#[napi(object, js_name = "NWeekday")]
pub struct NWeekday {
/// If set, this represents the nth occurrence of the weekday.
/// Otherwise it represents every occurrence of the weekday.
///
/// A negative value represents nth occurrence from the end.
pub n: Option<i16>,
pub weekday: Weekday,
}

impl From<rrule::NWeekday> for NWeekday {
fn from(nday: rrule::NWeekday) -> Self {
match nday {
rrule::NWeekday::Every(weekday) => NWeekday {
n: None,
weekday: Weekday::from(weekday),
},
rrule::NWeekday::Nth(n, weekday) => NWeekday {
n: Some(n),
weekday: weekday.into(),
},
impl Into<n_weekday::NWeekday> for NWeekday {
fn into(self) -> n_weekday::NWeekday {
n_weekday::NWeekday {
n: self.n,
weekday: self.weekday.into(),
}
}
}

impl Into<rrule::NWeekday> for NWeekday {
fn into(self) -> rrule::NWeekday {
match self.n {
Some(n) => rrule::NWeekday::Nth(n, self.weekday.into()),
None => rrule::NWeekday::Every(self.weekday.into()),
impl From<&n_weekday::NWeekday> for NWeekday {
fn from(n_weekday: &n_weekday::NWeekday) -> Self {
Self {
n: n_weekday.n,
weekday: (&n_weekday.weekday).into(),
}
}
}

impl Into<String> for &NWeekday {
fn into(self) -> String {
match self.n {
Some(n) => {
let n = if n > 1 || n < 0 {
n.to_string()
} else {
"".to_string()
};
let weekday: String = self.weekday.into();

format!("{}{}", n, weekday)
}
None => self.weekday.into(),
}
}
}

impl FromStr for NWeekday {
type Err = String;

fn from_str(str: &str) -> Result<Self, Self::Err> {
let weekday = extract_weekday(str)?;
let n = if str.len() > 2 {
Some(extract_number(str)?)
} else {
None
};

Ok(NWeekday { n, weekday })
}
}

fn extract_weekday(str: &str) -> Result<Weekday, String> {
let weekday = str
.chars()
.rev()
.take(2)
.collect::<String>()
.chars()
.rev()
.collect::<String>();

weekday.parse()
}

fn extract_number(str: &str) -> Result<i16, String> {
let number = str
.chars()
.take_while(|c| c.is_digit(10) || *c == '-')
.collect::<String>();

number
.parse()
.map_err(|_| format!("Invalid number: {}", number))
}
Loading

0 comments on commit 7ff6e79

Please sign in to comment.