Add support to allow the week day start in cal to be configured via a flag (#1996)

* Add support to allow the week day start in cal to be configurable

* Fix variable name

* Use a flag instead of a configuration setting for specifying the starting day of the week
This commit is contained in:
Joseph T. Lyons 2020-06-18 13:34:51 -04:00 committed by GitHub
parent 96d58094cf
commit 353b33be1b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 78 additions and 13 deletions

View file

@ -24,6 +24,12 @@ impl WholeStreamCommand for Cal {
"Display a year-long calendar for the specified year",
None,
)
.named(
"week-start",
SyntaxShape::String,
"Display the calendar with the specified day as the first day of the week",
None,
)
.switch(
"month-names",
"Display the month names instead of integers",
@ -55,6 +61,11 @@ impl WholeStreamCommand for Cal {
example: "cal --full-year 2012",
result: None,
},
Example {
description: "This month's calendar with the week starting on monday",
example: "cal --week-start monday",
result: None,
},
]
}
}
@ -226,11 +237,7 @@ fn add_month_to_table(
},
};
let day_limit =
month_helper.number_of_days_in_month + month_helper.day_number_of_week_month_starts_on;
let mut day_count: u32 = 1;
let days_of_the_week = [
let mut days_of_the_week = [
"sunday",
"monday",
"tuesday",
@ -240,12 +247,43 @@ fn add_month_to_table(
"saturday",
];
let mut week_start_day = days_of_the_week[0].to_string();
if let Some(week_start_value) = args.get("week-start") {
if let Ok(day) = week_start_value.as_string() {
if days_of_the_week.contains(&day.as_str()) {
week_start_day = day;
} else {
return Err(ShellError::labeled_error(
"The specified week start day is invalid",
"invalid week start day",
week_start_value.tag(),
));
}
}
}
let week_start_day_offset = days_of_the_week.len()
- days_of_the_week
.iter()
.position(|day| *day == week_start_day)
.unwrap_or(0);
days_of_the_week.rotate_right(week_start_day_offset);
let mut total_start_offset: u32 =
month_helper.day_number_of_week_month_starts_on + week_start_day_offset as u32;
total_start_offset %= days_of_the_week.len() as u32;
let mut day_number: u32 = 1;
let day_limit: u32 = total_start_offset + month_helper.number_of_days_in_month;
let should_show_year_column = args.has("year");
let should_show_quarter_column = args.has("quarter");
let should_show_month_column = args.has("month");
let should_show_month_names = args.has("month-names");
while day_count <= day_limit {
while day_number <= day_limit {
let mut indexmap = IndexMap::new();
if should_show_year_column {
@ -273,19 +311,18 @@ fn add_month_to_table(
}
for day in &days_of_the_week {
let should_add_day_number_to_table = (day_count <= day_limit)
&& (day_count > month_helper.day_number_of_week_month_starts_on);
let should_add_day_number_to_table =
(day_number > total_start_offset) && (day_number <= day_limit);
let mut value = UntaggedValue::nothing().into_value(tag);
if should_add_day_number_to_table {
let day_count_with_offset =
day_count - month_helper.day_number_of_week_month_starts_on;
let adjusted_day_number = day_number - total_start_offset;
value = UntaggedValue::int(day_count_with_offset).into_value(tag);
value = UntaggedValue::int(adjusted_day_number).into_value(tag);
if let Some(current_day) = current_day_option {
if current_day == day_count_with_offset {
if current_day == adjusted_day_number {
// TODO: Update the value here with a color when color support is added
// This colors the current day
}
@ -294,7 +331,7 @@ fn add_month_to_table(
indexmap.insert((*day).to_string(), value);
day_count += 1;
day_number += 1;
}
calendar_vec_deque

View file

@ -52,6 +52,20 @@ fn cal_rows_in_2020() {
assert!(actual.out.contains("62"));
}
#[test]
fn cal_week_day_start_monday() {
let actual = nu!(
cwd: ".", pipeline(
r#"
cal --full-year 2020 -m --month-names --week-start monday | where month == january | to json
"#
));
let cal_january_json = r#"[{"month":"january","monday":null,"tuesday":null,"wednesday":1,"thursday":2,"friday":3,"saturday":4,"sunday":5},{"month":"january","monday":6,"tuesday":7,"wednesday":8,"thursday":9,"friday":10,"saturday":11,"sunday":12},{"month":"january","monday":13,"tuesday":14,"wednesday":15,"thursday":16,"friday":17,"saturday":18,"sunday":19},{"month":"january","monday":20,"tuesday":21,"wednesday":22,"thursday":23,"friday":24,"saturday":25,"sunday":26},{"month":"january","monday":27,"tuesday":28,"wednesday":29,"thursday":30,"friday":31,"saturday":null,"sunday":null}]"#;
assert_eq!(actual.out, cal_january_json);
}
#[test]
fn cal_sees_pipeline_year() {
let actual = nu!(

View file

@ -8,6 +8,7 @@ Use `cal` to display a calendar.
* `-q`, `--quarter`: Display the quarter column
* `-m`, `--month`: Display the month column
* `--full-year` \<integer>: Display a year-long calendar for the specified year
* `--week-start` \<string>: Display the calendar with the specified day as the first day of the week
* `--month-names`: Display the month names instead of integers
## Examples
@ -188,3 +189,16 @@ Use `cal` to display a calendar.
1 │ 2020 │ november │ 8 │ 9 │ 10 │ 11 │ 12 │ 13 │ 14
───┴──────┴──────────┴────────┴────────┴─────────┴───────────┴──────────┴────────┴──────────
```
```shell
> cal -ymq --month-names --week-start-day monday
───┬──────┬─────────┬───────┬────────┬─────────┬───────────┬──────────┬────────┬──────────┬────────
# │ year │ quarter │ month │ monday │ tuesday │ wednesday │ thursday │ friday │ saturday │ sunday
───┼──────┼─────────┼───────┼────────┼─────────┼───────────┼──────────┼────────┼──────────┼────────
0 │ 2020 │ 2 │ june │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7
1 │ 2020 │ 2 │ june │ 8 │ 9 │ 10 │ 11 │ 12 │ 13 │ 14
2 │ 2020 │ 2 │ june │ 15 │ 16 │ 17 │ 18 │ 19 │ 20 │ 21
3 │ 2020 │ 2 │ june │ 22 │ 23 │ 24 │ 25 │ 26 │ 27 │ 28
4 │ 2020 │ 2 │ june │ 29 │ 30 │ │ │ │ │
───┴──────┴─────────┴───────┴────────┴─────────┴───────────┴──────────┴────────┴──────────┴────────
```