on master help sign in
Remove dependency on gregorian crate
commit2a0c685a7857a94db2ac61b586c92425da273ea7 authorJason Rodney Hansen <jasonrodneyhansen@gmail.com> dateSun 21 Nov 2021, 09:36 (5 years ago) parent64afd54
3 files changed+75−38
Cargo.lock+1−7 helix-core/Cargo.toml+1−1 helix-core/src/date.rs+73−30
Cargo.lock+1−7
@@ -325,12 +325,6 @@ dependencies = [
325325 "regex",
326326]
327327
328−[[package]]
329−name = "gregorian"
330−version = "0.2.1"
331−source = "registry+https://github.com/rust-lang/crates.io-index"
332−checksum = "3452972f2c995c38dc9b84f09fe14f1ca462a0580642fe6756fed58fdef29050"
333−
334328[[package]]
335329name = "grep-matcher"
336330version = "0.1.5"
@@ -375,8 +369,8 @@ name = "helix-core"
375369version = "0.5.0"
376370dependencies = [
377371 "arc-swap",
372+ "chrono",
378373 "etcetera",
379− "gregorian",
380374 "helix-syntax",
381375 "log",
382376 "once_cell",
helix-core/Cargo.toml+1−1
@@ -36,7 +36,7 @@ similar = "2.1"
3636
3737etcetera = "0.3"
3838
39−gregorian = { version = "0.2.1", default-features = false }
39+chrono = { version = "0.4", default-features = false, features = ["alloc", "std"] }
4040
4141[dev-dependencies]
4242quickcheck = { version = "1", default-features = false }
helix-core/src/date.rs+73−30
@@ -1,12 +1,61 @@
1−use gregorian::{Date, DateResultExt};
21use regex::Regex;
32
43use std::borrow::Cow;
4+use std::cmp;
55
66use ropey::RopeSlice;
77
88use crate::{Range, Tendril};
99
10+use chrono::{Datelike, Duration, NaiveDate};
11+
12+fn ndays_in_month(year: i32, month: u32) -> u32 {
13+ // The first day of the next month...
14+ let (y, m) = if month == 12 {
15+ (year + 1, 1)
16+ } else {
17+ (year, month + 1)
18+ };
19+ let d = NaiveDate::from_ymd(y, m, 1);
20+
21+ // ...is preceded by the last day of the original month.
22+ d.pred().day()
23+}
24+
25+fn add_days(date: NaiveDate, amount: i64) -> Option<NaiveDate> {
26+ date.checked_add_signed(Duration::days(amount))
27+}
28+
29+fn add_months(date: NaiveDate, amount: i64) -> Option<NaiveDate> {
30+ let month = date.month0() as i64 + amount;
31+ let year = date.year() + i32::try_from(month / 12).ok()?;
32+
33+ // Normalize month
34+ let month = month % 12;
35+ let month = if month.is_negative() {
36+ month + 13
37+ } else {
38+ month + 1
39+ } as u32;
40+
41+ let day = cmp::min(date.day(), ndays_in_month(year, month));
42+
43+ Some(NaiveDate::from_ymd(year, month, day))
44+}
45+
46+fn add_years(date: NaiveDate, amount: i64) -> Option<NaiveDate> {
47+ let year = i32::try_from(date.year() as i64 + amount).ok()?;
48+
49+ let ndays = ndays_in_month(year, date.month());
50+
51+ if date.day() > ndays {
52+ let d = NaiveDate::from_ymd(year, date.month(), ndays);
53+ Some(d.succ())
54+ } else {
55+ date.with_year(year)
56+ }
57+}
58+
1059#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1160struct Format {
1261 regex: &'static str,
@@ -36,7 +85,7 @@ enum DateField {
3685
3786#[derive(Debug, PartialEq, Eq)]
3887pub struct DateIncrementor {
39− pub date: Date,
88+ pub date: NaiveDate,
4089 pub range: Range,
4190
4291 field: DateField,
@@ -87,12 +136,11 @@ impl DateIncrementor {
87136 return None;
88137 };
89138
90− let date = Date::new(
91− year.as_str().parse::<i16>().ok()?,
92− month.as_str().parse::<u8>().ok()?,
93− day.as_str().parse::<u8>().ok()?,
94− )
95− .ok()?;
139+ let date = NaiveDate::from_ymd_opt(
140+ year.as_str().parse::<i32>().ok()?,
141+ month.as_str().parse::<u32>().ok()?,
142+ day.as_str().parse::<u32>().ok()?,
143+ )?;
96144
97145 Some(DateIncrementor {
98146 date,
@@ -105,22 +153,17 @@ impl DateIncrementor {
105153
106154 pub fn incremented_text(&self, amount: i64) -> Tendril {
107155 let date = match self.field {
108− DateField::Year => self
109− .date
110− .add_years(amount.try_into().unwrap_or(0))
111− .or_next_valid(),
112− DateField::Month => self
113− .date
114− .add_months(amount.try_into().unwrap_or(0))
115− .or_prev_valid(),
116− DateField::Day => self.date.add_days(amount.try_into().unwrap_or(0)),
117− };
156+ DateField::Year => add_years(self.date, amount),
157+ DateField::Month => add_months(self.date, amount),
158+ DateField::Day => add_days(self.date, amount),
159+ }
160+ .unwrap_or(self.date);
118161
119162 format!(
120163 "{:04}{}{:02}{}{:02}",
121164 date.year(),
122165 self.format.separator,
123− date.month().to_number(),
166+ date.month(),
124167 self.format.separator,
125168 date.day()
126169 )
@@ -142,7 +185,7 @@ mod test {
142185 assert_eq!(
143186 DateIncrementor::from_range(rope.slice(..), range),
144187 Some(DateIncrementor {
145− date: Date::new(2021, 11, 15).unwrap(),
188+ date: NaiveDate::from_ymd(2021, 11, 15),
146189 range: Range::new(0, 10),
147190 field: DateField::Year,
148191 format: FORMATS[0],
@@ -160,7 +203,7 @@ mod test {
160203 assert_eq!(
161204 DateIncrementor::from_range(rope.slice(..), range),
162205 Some(DateIncrementor {
163− date: Date::new(2021, 11, 15).unwrap(),
206+ date: NaiveDate::from_ymd(2021, 11, 15),
164207 range: Range::new(0, 10),
165208 field: DateField::Month,
166209 format: FORMATS[0],
@@ -178,7 +221,7 @@ mod test {
178221 assert_eq!(
179222 DateIncrementor::from_range(rope.slice(..), range),
180223 Some(DateIncrementor {
181− date: Date::new(2021, 11, 15).unwrap(),
224+ date: NaiveDate::from_ymd(2021, 11, 15),
182225 range: Range::new(0, 10),
183226 field: DateField::Day,
184227 format: FORMATS[0],
@@ -206,7 +249,7 @@ mod test {
206249 assert_eq!(
207250 DateIncrementor::from_range(rope.slice(..), range),
208251 Some(DateIncrementor {
209− date: Date::new(2021, 11, 15).unwrap(),
252+ date: NaiveDate::from_ymd(2021, 11, 15),
210253 range: Range::new(0, 10),
211254 field: DateField::Year,
212255 format: FORMATS[1],
@@ -224,7 +267,7 @@ mod test {
224267 assert_eq!(
225268 DateIncrementor::from_range(rope.slice(..), range),
226269 Some(DateIncrementor {
227− date: Date::new(2021, 11, 15).unwrap(),
270+ date: NaiveDate::from_ymd(2021, 11, 15),
228271 range: Range::new(0, 10),
229272 field: DateField::Month,
230273 format: FORMATS[1],
@@ -242,7 +285,7 @@ mod test {
242285 assert_eq!(
243286 DateIncrementor::from_range(rope.slice(..), range),
244287 Some(DateIncrementor {
245− date: Date::new(2021, 11, 15).unwrap(),
288+ date: NaiveDate::from_ymd(2021, 11, 15),
246289 range: Range::new(0, 10),
247290 field: DateField::Day,
248291 format: FORMATS[1],
@@ -268,7 +311,7 @@ mod test {
268311 assert_eq!(
269312 DateIncrementor::from_range(rope.slice(..), range),
270313 Some(DateIncrementor {
271− date: Date::new(2021, 11, 15).unwrap(),
314+ date: NaiveDate::from_ymd(2021, 11, 15),
272315 range: Range::new(3, 13),
273316 field: DateField::Year,
274317 format: FORMATS[0],
@@ -283,7 +326,7 @@ mod test {
283326 assert_eq!(
284327 DateIncrementor::from_range(rope.slice(..), range),
285328 Some(DateIncrementor {
286− date: Date::new(2021, 11, 15).unwrap(),
329+ date: NaiveDate::from_ymd(2021, 11, 15),
287330 range: Range::new(8, 18),
288331 field: DateField::Year,
289332 format: FORMATS[0],
@@ -298,7 +341,7 @@ mod test {
298341 assert_eq!(
299342 DateIncrementor::from_range(rope.slice(..), range),
300343 Some(DateIncrementor {
301− date: Date::new(2021, 11, 15).unwrap(),
344+ date: NaiveDate::from_ymd(2021, 11, 15),
302345 range: Range::new(12, 22),
303346 field: DateField::Year,
304347 format: FORMATS[0],
@@ -327,7 +370,7 @@ mod test {
327370 assert_eq!(
328371 DateIncrementor::from_range(rope.slice(..), range),
329372 Some(DateIncrementor {
330− date: Date::new(2021, 11, 15).unwrap(),
373+ date: NaiveDate::from_ymd(2021, 11, 15),
331374 range: Range::new(0, 10),
332375 field: DateField::Year,
333376 format: FORMATS[0],
@@ -342,7 +385,7 @@ mod test {
342385 assert_eq!(
343386 DateIncrementor::from_range(rope.slice(..), range),
344387 Some(DateIncrementor {
345− date: Date::new(2021, 11, 15).unwrap(),
388+ date: NaiveDate::from_ymd(2021, 11, 15),
346389 range: Range::new(0, 10),
347390 field: DateField::Month,
348391 format: FORMATS[0],