Skip to content

Commit

Permalink
add support for more events (#18)
Browse files Browse the repository at this point in the history
* add support for more events

* fix clippy lints

* create EventTime type

* bump version

* update README

* update cargo

* add new RuntimeErrorKind

* improve error handling
  • Loading branch information
mfreeborn authored Jun 28, 2020
1 parent f3133f8 commit 004f7f9
Show file tree
Hide file tree
Showing 13 changed files with 549 additions and 115 deletions.
18 changes: 9 additions & 9 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "heliocron"
version = "0.3.4"
version = "0.4.0"
authors = ["Michael Freeborn <[email protected]>"]
description = """
Heliocron is a command line application written in Rust capable of delaying execution of other
Expand Down
61 changes: 44 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ $ cargo install heliocron
.
.
$ heliocron --version
heliocron 0.3.3
heliocron 0.4.0
```

#### 3. Build from source
Expand All @@ -27,7 +27,7 @@ $ git clone https://github.com/mfreeborn/heliocron
$ cd heliocron
$ cargo build --release
$ ./target/release/heliocron --version
heliocron 0.3.3
heliocron 0.4.0
```

## Usage Examples
Expand Down Expand Up @@ -57,11 +57,20 @@ DATE
----
2065-05-07 12:00:00 +01:00
Sunrise is at: 05:14:52
Solar noon is at: 13:09:19
Sunset is at: 21:04:53
Solar noon is at: 2065-05-07 13:09:19 +01:00
The day length is: 15h 49m 51s
The day length is: 15:50:01
Sunrise is at: 2065-05-07 05:14:24 +01:00
Sunset is at: 2065-05-07 21:04:15 +01:00
Civil dawn is at: 2065-05-07 04:27:31 +01:00
Civil dusk is at: 2065-05-07 21:51:08 +01:00
Nautical dawn is at: 2065-05-07 03:19:56 +01:00
Nautical dusk is at: 2065-05-07 22:58:43 +01:00
Astronomical dawn is at: Never
Astronomical dusk is at: Never
```

### Configuration
Expand All @@ -77,18 +86,27 @@ Now, using Heliocron without providing specific coordinates will yield the follo
$ heliocron -d 2020-03-08 report
LOCATION
--------
Latitude: 51.5014N
Longitude: 0.1419W
Latitude: 51.4769N
Longitude: 0.0005W
DATE
----
2020-03-08 12:00:00 +00:00
Sunrise is at: 06:29:01
Solar noon is at: 12:11:12
Sunset is at: 17:53:23
Solar noon is at: 2020-03-08 12:10:38 +00:00
The day length is: 11h 24m 24s
Sunrise is at: 2020-03-08 06:28:26 +00:00
Sunset is at: 2020-03-08 17:52:50 +00:00
Civil dawn is at: 2020-03-08 05:55:11 +00:00
Civil dusk is at: 2020-03-08 18:26:05 +00:00
The day length is: 11:24:22
Nautical dawn is at: 2020-03-08 05:16:32 +00:00
Nautical dusk is at: 2020-03-08 19:04:44 +00:00
Astronomical dawn is at: 2020-03-08 04:37:08 +00:00
Astronomical dusk is at: 2020-03-08 19:44:08 +00:00
```
Observe that the location is set according to the contents of the configuration file.

Expand All @@ -97,16 +115,25 @@ Arguments passed in via the command line will override those set in the configur
$ heliocron -d 2020-03-08 -l 51.4839N -o 0.6044W report
LOCATION
--------
Latitude: 51.4839N
Latitude: 51.4839N
Longitude: 0.6044W
DATE
----
2020-03-08 12:00:00 +00:00
Sunrise is at: 06:30:51
Solar noon is at: 12:13:03
Sunset is at: 17:55:15
Solar noon is at: 2020-03-08 12:13:03 +00:00
The day length is: 11h 24m 24s
Sunrise is at: 2020-03-08 06:30:51 +00:00
Sunset is at: 2020-03-08 17:55:15 +00:00
Civil dawn is at: 2020-03-08 05:57:36 +00:00
Civil dusk is at: 2020-03-08 18:28:30 +00:00
Nautical dawn is at: 2020-03-08 05:18:56 +00:00
Nautical dusk is at: 2020-03-08 19:07:10 +00:00
The day length is: 11:24:24
Astronomical dawn is at: 2020-03-08 04:39:32 +00:00
Astronomical dusk is at: 2020-03-08 19:46:34 +00:00
```
2 changes: 1 addition & 1 deletion src/bin/heliocron.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ fn run_heliocron() -> Result<(), errors::HeliocronError> {
match config.subcommand {
Some(config::Subcommand::Report {}) => subcommands::display_report(report),
Some(config::Subcommand::Wait { offset, event }) => {
subcommands::wait(offset?, report, event?)
subcommands::wait(offset?, report, event?)?
}
// will never match None as this is caught earlier by StructOpt
None => println!("No subcommand provided!"),
Expand Down
24 changes: 16 additions & 8 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{fs, path::Path};
use std::{fs, path::Path, result};

use chrono::{DateTime, Duration, FixedOffset, Local, TimeZone};
use dirs;
Expand All @@ -11,11 +11,17 @@ use super::{
parsers, structs,
};

type Result<T> = std::result::Result<T, HeliocronError>;
type Result<T> = result::Result<T, HeliocronError>;

#[derive(Debug, StructOpt)]
#[structopt(
about = "A simple utility for finding out what time sunrise/sunset is, and executing programs relative to these events."
about = "A simple utility for finding out what time various solar events occur, such as sunrise and \
sunset, at a given location on a given date. It can be integrated into cron commands to \
trigger program execution relative to these events.\n\n\
For example, to execute a script 'turn-on-lights.sh' at sunrise, make a Crontab entry to trigger \
at a time that will always be before the chosen event (say, 2am) and use heliocron to calculate \
and perform the appropriate delay:\n\n\
\t0 2 * * * heliocron --latitude 51.47N --longitude 3.1W wait --event sunrise && turn-on-lights.sh"
)]
struct Cli {
#[structopt(subcommand)]
Expand All @@ -24,18 +30,20 @@ struct Cli {
#[structopt(flatten)]
date_args: DateArgs,

// the default values for latitude and longitude are handled differently to enable the user to set the values
// either on the command line, in a config file or have a default provided by the program
#[structopt(
short = "l",
long = "latitude",
help = "Set the latitude in decimal degrees. The default is \"51.4769N\" unless overridden in ~/.config/heliocron.toml",
help = "Set the latitude in decimal degrees. Can also be set in ~/.config/heliocron.toml. [default: 51.4769N]",
requires = "longitude"
)]
latitude: Option<String>,

#[structopt(
short = "o",
long = "longitude",
help = "Set the longitude in decimal degrees. The default is \"0.0005W\" unless overridden in ~/.config/heliocron.toml",
help = "Set the longitude in decimal degrees. Can also be set in ~/.config/heliocron.toml. [default: 0.0005W]",
requires = "latitude"
)]
longitude: Option<String>,
Expand All @@ -57,11 +65,11 @@ pub enum Subcommand {
offset: Result<Duration>,

#[structopt(
help = "Choose one of {sunrise | sunset} from which to base your delay.",
help = "Choose an event from which to base your delay.",
short = "e",
long = "event",
parse(from_str=parsers::parse_event),
possible_values = &["sunrise", "sunset"]
possible_values = &["sunrise", "sunset", "civil_dawn", "civil_dusk", "nautical_dawn", "nautical_dusk", "astronomical_dawn", "astronomical_dusk"]
)]
event: Result<enums::Event>,
},
Expand Down Expand Up @@ -93,7 +101,7 @@ impl TomlConfig {
}
}

fn from_toml(config: std::result::Result<TomlConfig, toml::de::Error>) -> TomlConfig {
fn from_toml(config: result::Result<TomlConfig, toml::de::Error>) -> TomlConfig {
match config {
Ok(conf) => conf,
_ => TomlConfig::new(),
Expand Down
19 changes: 19 additions & 0 deletions src/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ type Result<T> = result::Result<T, HeliocronError>;
pub enum Event {
Sunrise,
Sunset,
CivilDawn,
CivilDusk,
NauticalDawn,
NauticalDusk,
AstronomicalDawn,
AstronomicalDusk,
}

impl Event {
Expand All @@ -16,7 +22,20 @@ impl Event {
match event.as_str() {
"sunrise" => Ok(Event::Sunrise),
"sunset" => Ok(Event::Sunset),
"civil_dawn" => Ok(Event::CivilDawn),
"civil_dusk" => Ok(Event::CivilDusk),
"nautical_dawn" => Ok(Event::NauticalDawn),
"nautical_dusk" => Ok(Event::NauticalDusk),
"astronomical_dawn" => Ok(Event::AstronomicalDawn),
"astronomical_dusk" => Ok(Event::AstronomicalDusk),
_ => Err(HeliocronError::Config(ConfigErrorKind::InvalidEvent)),
}
}
}

#[derive(Debug)]
pub enum TwilightType {
Civil,
Nautical,
Astronomical,
}
31 changes: 28 additions & 3 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use chrono;
#[derive(Debug)]
pub enum HeliocronError {
Config(ConfigErrorKind),
Runtime(RuntimeErrorKind),
}

#[derive(Debug)]
Expand All @@ -20,13 +21,28 @@ impl ConfigErrorKind {
match *self {
ConfigErrorKind::InvalidCoordindates(msg) => msg,
ConfigErrorKind::InvalidTomlFile => {
"Error parsing .toml file. Ensure that it is of the correct format."
"Error parsing TOML file. Ensure that it is of the correct format."
}
ConfigErrorKind::ParseDate => {
"Error parsing date. Ensure the date and timezone formats are correct."
}
ConfigErrorKind::InvalidEvent => {
"Error parsing event. Expected one of {'sunrise' | 'sunset'}"
ConfigErrorKind::InvalidEvent => "Error parsing event.",
}
}
}

#[derive(Debug)]
pub enum RuntimeErrorKind {
NonOccurringEvent,
PastEvent,
}

impl RuntimeErrorKind {
fn as_str(&self) -> &str {
match *self {
RuntimeErrorKind::NonOccurringEvent => "The chosen event does not occur on this day.",
RuntimeErrorKind::PastEvent => {
"The chosen event occurred in the past; cannot wait a negative amount of time."
}
}
}
Expand All @@ -46,6 +62,14 @@ impl std::fmt::Display for HeliocronError {
ConfigErrorKind::InvalidEvent => err.as_str().to_string(),
}
),
HeliocronError::Runtime(ref err) => write!(
f,
"Runtime error: {}",
match err {
RuntimeErrorKind::NonOccurringEvent => err.as_str().to_string(),
RuntimeErrorKind::PastEvent => err.as_str().to_string(),
}
),
}
}
}
Expand All @@ -54,6 +78,7 @@ impl error::Error for HeliocronError {
fn description(&self) -> &str {
match *self {
HeliocronError::Config(ref err) => err.as_str(),
HeliocronError::Runtime(ref err) => err.as_str(),
}
}
}
Expand Down
Loading

0 comments on commit 004f7f9

Please sign in to comment.