No more expect, we use Result now
continuous-integration/drone/push Build is passing Details

main
Julius 2021-12-07 19:40:41 +01:00
parent 605921453d
commit c75d35d80d
Signed by: j00lz
GPG Key ID: AF241B0AA237BBA2
11 changed files with 246 additions and 193 deletions

7
Cargo.lock generated
View File

@ -11,10 +11,17 @@ dependencies = [
"winapi",
]
[[package]]
name = "anyhow"
version = "1.0.51"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b26702f315f53b6071259e15dd9d64528213b44d61de1ec926eca7715d62203"
[[package]]
name = "aoc2021"
version = "0.1.0"
dependencies = [
"anyhow",
"chrono",
"clap",
]

View File

@ -8,3 +8,4 @@ edition = "2021"
[dependencies]
clap = "2.34.0"
chrono = "0.4.19"
anyhow = "1.0.51"

View File

@ -1,5 +1,7 @@
use anyhow::Result;
pub trait Day {
fn init(content: String) -> Self where Self: Sized;
fn part1(&self) -> String;
fn part2(&self) -> String;
fn init(content: String) -> Result<Self> where Self: Sized;
fn part1(&self) -> Result<String>;
fn part2(&self) -> Result<String>;
}

View File

@ -1,21 +1,22 @@
use anyhow::Result;
pub struct Day01(Vec<i32>);
impl crate::day::Day for Day01 {
fn init(f: String) -> Self {
let v = f.lines().map(|x| x.parse::<i32>().unwrap()).collect::<Vec<i32>>();
Self(v)
fn init(f: String) -> Result<Self> {
let v = f.lines().map(str::parse).collect::<Result<Vec<_>, _>>()?;
Ok(Self(v))
}
fn part1(&self) -> String {
fn part1(&self) -> Result<String> {
let (a, _) = self.0.iter().copied().fold((0, -1), increments);
format!("{}", a)
Ok(format!("{}", a))
}
fn part2(&self) -> String {
fn part2(&self) -> Result<String> {
let ws = self.0.windows(3).map(|a| a.iter().fold(0, std::ops::Add::add)).collect::<Vec<i32>>();
let (a, _) = ws.iter().copied().fold((0, -1), increments);
format!("{}", a)
Ok(format!("{}", a))
}
}
@ -37,32 +38,36 @@ pub mod tests {
use crate::day::Day;
#[test]
pub fn part1_real() {
let f = read_to_string("./input/day01").expect("Could not load input");
let d = Day01::init(f);
assert_eq!("1466", d.part1())
pub fn part1_real() -> anyhow::Result<()> {
let f = read_to_string("./input/day01")?;
let d = Day01::init(f)?;
assert_eq!("1466", d.part1()?);
Ok(())
}
#[test]
pub fn part2_real() {
let f = read_to_string("./input/day01").expect("Could not load input");
let d = Day01::init(f);
assert_eq!("1491", d.part2())
pub fn part2_real() -> anyhow::Result<()> {
let f = read_to_string("./input/day01")?;
let d = Day01::init(f)?;
assert_eq!("1491", d.part2()?);
Ok(())
}
#[test]
pub fn part1_test() {
pub fn part1_test() -> anyhow::Result<()>{
let v = vec![199, 200, 208, 210, 200, 207, 240, 269, 260, 263];
let strs = v.iter().map(i32::to_string).collect::<Vec<String>>().join("\n");
let d = Day01::init(strs);
assert_eq!("7", d.part1())
let d = Day01::init(strs)?;
assert_eq!("7", d.part1()?);
Ok(())
}
#[test]
pub fn part2_test() {
pub fn part2_test() -> anyhow::Result<()>{
let v = vec![199, 200, 208, 210, 200, 207, 240, 269, 260, 263];
let strs = v.iter().map(i32::to_string).collect::<Vec<String>>().join("\n");
let d = Day01::init(strs);
assert_eq!("5", d.part2())
let d = Day01::init(strs)?;
assert_eq!("5", d.part2()?);
Ok(())
}
}

View File

@ -1,4 +1,5 @@
use crate::Day;
use anyhow::Result;
pub struct Day02(Vec<Instruction>);
@ -9,12 +10,12 @@ enum Instruction {
}
impl Day for Day02 {
fn init(content: String) -> Self {
let lines = content.lines().map(str_to_instr).collect::<Vec<Instruction>>();
Day02(lines)
fn init(content: String) -> Result<Self> {
let lines = content.lines().map(str_to_instr).collect::<Result<Vec<Instruction>>>()?;
Ok(Self(lines))
}
fn part1(&self) -> String {
fn part1(&self) -> Result<String> {
let mut depth = 0;
let mut fw = 0;
for i in &self.0 {
@ -24,10 +25,10 @@ impl Day for Day02 {
Instruction::Up(n) => depth -= n,
}
}
format!("{}", depth * fw)
Ok(format!("{}", depth * fw))
}
fn part2(&self) -> String {
fn part2(&self) -> Result<String> {
let mut depth = 0;
let mut fw = 0;
let mut aim = 0;
@ -41,19 +42,19 @@ impl Day for Day02 {
Instruction::Up(n) => aim -= n,
}
}
format!("{}", depth * fw)
Ok(format!("{}", depth * fw))
}
}
fn str_to_instr(s: &str) -> Instruction {
fn str_to_instr(s: &str) -> Result<Instruction> {
let v = s.split(' ').collect::<Vec<&str>>();
let name = v[0];
let height = v[1].parse().expect("This should be an int :p");
let height = v[1].parse()?;
match name {
"forward" => Instruction::Forward(height),
"up" => Instruction::Up(height),
"down" => Instruction::Down(height),
_ => panic!("How did this happen???")
"forward" => Ok(Instruction::Forward(height)),
"up" => Ok(Instruction::Up(height)),
"down" => Ok(Instruction::Down(height)),
_ => Err(anyhow::Error::msg("This is not a valid direction!"))
}
}
@ -62,6 +63,7 @@ mod tests {
use std::fs::read_to_string;
use crate::day02::Day02;
use crate::day::Day;
use super::Result;
const D: &str = r"forward 5
down 5
@ -71,28 +73,28 @@ down 8
forward 2";
#[test]
fn part1_test() {
let d2 = Day02::init(String::from(D));
assert_eq!("150", d2.part1())
fn part1_test() -> Result<()> {
let d2 = Day02::init(String::from(D))?;
Ok(assert_eq!("150", d2.part1()?))
}
#[test]
fn part2_test() {
let d2 = Day02::init(String::from(D));
assert_eq!("900", d2.part2())
fn part2_test() -> Result<()> {
let d2 = Day02::init(String::from(D))?;
Ok(assert_eq!("900", d2.part2()?))
}
#[test]
pub fn part1_real() {
let f = read_to_string("./input/day02").expect("Could not load input");
let d = Day02::init(f);
assert_eq!("1524750", d.part1())
pub fn part1_real() -> Result<()> {
let f = read_to_string("./input/day02")?;
let d = Day02::init(f)?;
Ok(assert_eq!("1524750", d.part1()?))
}
#[test]
pub fn part2_real() {
let f = read_to_string("./input/day02").expect("Could not load input");
let d = Day02::init(f);
assert_eq!("1592426537", d.part2())
pub fn part2_real()-> Result<()> {
let f = read_to_string("./input/day02")?;
let d = Day02::init(f)?;
Ok(assert_eq!("1592426537", d.part2()?))
}
}

View File

@ -1,19 +1,20 @@
use crate::Day;
use anyhow::Result;
pub struct Day03(Vec<Vec<bool>>);
impl Day for Day03 {
fn init(content: String) -> Self {
fn init(content: String) -> Result<Self> {
let v = content.lines().map(split_lines).collect();
Self(v)
Ok(Self(v))
}
fn part1(&self) -> String {
format!("{}", self.gamma() * self.epsilon())
fn part1(&self) -> Result<String> {
Ok(format!("{}", self.gamma() * self.epsilon()))
}
fn part2(&self) -> String {
format!("{}", self.ox() * self.co2())
fn part2(&self) -> Result<String> {
Ok(format!("{}", self.ox() * self.co2()))
}
}
@ -127,6 +128,7 @@ mod tests {
use crate::Day03;
use crate::day::Day;
use anyhow::Result;
const INPUT: &str = r"00100
11110
@ -142,32 +144,36 @@ mod tests {
01010";
#[test]
fn part1_test() {
let t = Day03::init(String::from(INPUT));
let p1 = t.part1();
assert_eq!("198", p1)
fn part1_test() -> Result<()>{
let t = Day03::init(String::from(INPUT))?;
let p1 = t.part1()?;
assert_eq!("198", p1);
Ok(())
}
#[test]
fn part2_test() {
let t = Day03::init(String::from(INPUT));
let p2 = t.part2();
assert_eq!("230", p2)
fn part2_test() -> Result<()>{
let t = Day03::init(String::from(INPUT))?;
let p2 = t.part2()?;
assert_eq!("230", p2);
Ok(())
}
#[test]
fn part1_real() {
let f = read_to_string("./input/day03").expect("Could not load input");
let t = Day03::init(f);
let p1 = t.part1();
assert_eq!("4118544", p1)
fn part1_real() -> Result<()>{
let f = read_to_string("./input/day03")?;
let t = Day03::init(f)?;
let p1 = t.part1()?;
assert_eq!("4118544", p1);
Ok(())
}
#[test]
fn part2_real() {
let f = read_to_string("./input/day03").expect("Could not load input");
let t = Day03::init(f);
let p2 = t.part2();
assert_eq!("3832770", p2)
fn part2_real() -> Result<()>{
let f = read_to_string("./input/day03")?;
let t = Day03::init(f)?;
let p2 = t.part2()?;
assert_eq!("3832770", p2);
Ok(())
}
}

View File

@ -1,4 +1,5 @@
use crate::Day;
use anyhow::Result;
#[derive(Clone)]
pub struct Day04 {
@ -10,11 +11,11 @@ pub struct Day04 {
struct Board(Vec<Vec<Option<u32>>>);
impl Day for Day04 {
fn init(content: String) -> Self where Self: Sized {
fn init(content: String) -> Result<Self> {
let l = content.lines().collect::<Vec<&str>>();
let (a, b) = l.split_at(2);
let first = a[0];
let nums = first.split(',').map(|x| x.parse::<u32>().expect("wat?")).collect();
let nums = first.split(',').map(str::parse).collect::<Result<Vec<_>, _>>()?;
let split = b.split(|x| x.is_empty());
@ -25,13 +26,13 @@ impl Day for Day04 {
).map(Option::Some).collect()).collect()
).map(Board).collect();
Day04 {
Ok(Self {
numbers: nums,
boards,
}
})
}
fn part1(&self) -> String {
fn part1(&self) -> Result<String> {
let z = self.clone();
let mut boards = z.boards;
for number in z.numbers {
@ -39,15 +40,15 @@ impl Day for Day04 {
let res = board.mark(number);
if res {
let s = board.unmarked_sum();
return format!("{}", s * number);
return Ok(format!("{}", s * number));
}
}
}
panic!("no board can win?")
Err(anyhow::Error::msg("could not find a working sum..."))
}
fn part2(&self) -> String {
fn part2(&self) -> Result<String> {
let z = self.clone();
let mut boards = z.boards;
for number in z.numbers {
@ -56,13 +57,13 @@ impl Day for Day04 {
let res = board.mark(number);
if res && len == 1 {
let s = board.unmarked_sum();
return format!("{}", s * number);
return Ok(format!("{}", s * number));
}
}
boards = boards.iter().filter(|x| !x.complete()).cloned().collect();
}
panic!("no board can win?")
Err(anyhow::Error::msg("could not find a working sum..."))
}
}
@ -130,6 +131,7 @@ mod tests {
use crate::Day04;
use crate::day04::Board;
use crate::day::Day;
use anyhow::Result;
const INPUT: &str = r"7,4,9,5,11,17,23,2,0,14,21,24,10,16,13,6,15,25,12,22,18,20,8,19,3,26,1
@ -190,33 +192,37 @@ mod tests {
}
#[test]
fn part1_test() {
let t = Day04::init(INPUT.to_string());
let p1 = t.part1();
assert_eq!("4512", p1)
fn part1_test() -> Result<()> {
let t = Day04::init(INPUT.to_string())?;
let p1 = t.part1()?;
assert_eq!("4512", p1);
Ok(())
}
#[test]
fn part2_test() {
let t = Day04::init(INPUT.to_string());
let p2 = t.part2();
assert_eq!("1924", p2)
fn part2_test() -> Result<()> {
let t = Day04::init(INPUT.to_string())?;
let p2 = t.part2()?;
assert_eq!("1924", p2);
Ok(())
}
#[test]
fn part1_real() {
let f = read_to_string("./input/day04").expect("Could not load input");
let t = Day04::init(f);
let p1 = t.part1();
assert_eq!("8136", p1)
fn part1_real() -> Result<()> {
let f = read_to_string("./input/day04")?;
let t = Day04::init(f)?;
let p1 = t.part1()?;
assert_eq!("8136", p1);
Ok(())
}
#[test]
fn part2_real() {
let f = read_to_string("./input/day04").expect("Could not load input");
let t = Day04::init(f);
let p2 = t.part2();
assert_eq!("12738", p2)
fn part2_real() -> Result<()> {
let f = read_to_string("./input/day04")?;
let t = Day04::init(f)?;
let p2 = t.part2()?;
assert_eq!("12738", p2);
Ok(())
}
}

View File

@ -1,10 +1,9 @@
use std::cmp::Ordering;
use std::collections::HashMap;
use crate::Day;
use anyhow::Result;
pub struct Day05 {
vents: Vec<Path>,
}
pub struct Day05(Vec<Path>);
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
struct Path {
@ -20,20 +19,18 @@ struct Coordinate {
}
impl Day for Day05 {
fn init(content: String) -> Self {
let paths = content.lines().map(str_to_vent).collect::<Vec<Path>>();
Self {
vents: paths,
}
fn init(content: String) -> Result<Self> {
let paths = content.lines().map(str_to_vent).collect::<Result<Vec<Path>, _>>()?;
Ok(Self(paths))
}
fn part1(&self) -> String {
let new_vents = self.vents.iter().filter(|p| p.is_straight()).cloned().collect::<Vec<Path>>();
format!("{}", covered_twice(&new_vents))
fn part1(&self) -> Result<String> {
let new_vents = self.0.iter().filter(|p| p.is_straight()).cloned().collect::<Vec<Path>>();
Ok(format!("{}", covered_twice(&new_vents)))
}
fn part2(&self) -> String {
format!("{}", covered_twice(&self.vents))
fn part2(&self) -> Result<String> {
Ok(format!("{}", covered_twice(&self.0)))
}
}
@ -115,12 +112,12 @@ impl Direction {
}
}
fn str_to_vent(st: &str) -> Path {
fn str_to_vent(st: &str) -> Result<Path> {
let mut v = st.split(" -> ");
let a = v.next().unwrap();
let b = v.next().unwrap();
let start = a.split(',').map(|x| x.parse().unwrap()).collect::<Vec<i64>>();
let end = b.split(',').map(|x| x.parse().unwrap()).collect::<Vec<i64>>();
let a = v.next().ok_or_else(|| anyhow::Error::msg("could not get next..."))?;
let b = v.next().ok_or_else(|| anyhow::Error::msg("could not get next..."))?;
let start = a.split(',').map(str::parse).collect::<Result<Vec<i64>,_>>()?;
let end = b.split(',').map(str::parse).collect::<Result<Vec<i64>,_>>()?;
let start = Coordinate::from_vec(&start);
let end = Coordinate::from_vec(&end);
@ -135,11 +132,11 @@ fn str_to_vent(st: &str) -> Path {
}
covers.push(end.clone());
Path {
Ok(Path {
start,
end,
covers,
}
})
}
#[cfg(test)]
@ -147,6 +144,7 @@ mod tests {
use crate::Day05;
use crate::day05::{Coordinate, Direction};
use crate::day::Day;
use anyhow::Result;
const INPUT: &str = r"0,9 -> 5,9
8,0 -> 0,8
@ -172,26 +170,30 @@ mod tests {
}
#[test]
fn part1_test() {
let d = Day05::init(INPUT.to_string());
assert_eq!("5", d.part1());
fn part1_test() -> Result<()> {
let d = Day05::init(INPUT.to_string())?;
assert_eq!("5", d.part1()?);
Ok(())
}
#[test]
fn part2_test() {
let d = Day05::init(INPUT.to_string());
assert_eq!("12", d.part2());
fn part2_test() -> Result<()> {
let d = Day05::init(INPUT.to_string())?;
assert_eq!("12", d.part2()?);
Ok(())
}
#[test]
fn part1_real() {
let d = Day05::init(crate::load_input("05"));
assert_eq!("6564", d.part1());
fn part1_real() -> Result<()> {
let d = Day05::init(crate::load_input("05")?)?;
assert_eq!("6564", d.part1()?);
Ok(())
}
#[test]
fn part2_real() {
let d = Day05::init(crate::load_input("05"));
assert_eq!("19172", d.part2());
fn part2_real() -> Result<()> {
let d = Day05::init(crate::load_input("05")?)?;
assert_eq!("19172", d.part2()?);
Ok(())
}
}

View File

@ -1,23 +1,24 @@
use crate::Day;
use anyhow::Result;
pub struct Day06([u64; 9]);
impl Day for Day06 {
fn init(content: String) -> Self {
let c = content.split(',').map(|x| x.parse().expect("This is not an int!")).collect::<Vec<usize>>();
fn init(content: String) -> anyhow::Result<Self> {
let c = content.split(',').map(str::parse).collect::<Result<Vec<usize>, _>>()?;
let mut w: [u64; 9] = [0, 0, 0, 0, 0, 0, 0, 0, 0];
for z in c {
w[z as usize] += 1;
}
Self(w)
Ok(Self(w))
}
fn part1(&self) -> String {
format!("{}", self.do_magic(80))
fn part1(&self) -> Result<String> {
Ok(format!("{}", self.do_magic(80)))
}
fn part2(&self) -> String {
format!("{}", self.do_magic(256))
fn part2(&self) -> Result<String> {
Ok(format!("{}", self.do_magic(256)))
}
}
@ -35,30 +36,42 @@ impl Day06 {
mod tests {
use crate::day06::Day06;
use crate::day::Day;
use anyhow::Result;
const INPUT: &str = r"3,4,3,1,2";
#[test]
fn part1_test() {
let d = Day06::init(INPUT.to_string());
assert_eq!("5934", d.part1());
fn part1_test() -> Result<()> {
let d = Day06::init(INPUT.to_string())?;
assert_eq!("5934", d.part1()?);
Ok(())
}
#[test]
fn part2_test() {
let d = Day06::init(INPUT.to_string());
assert_eq!("26984457539", d.part2());
fn part2_test() -> Result<()> {
let d = Day06::init(INPUT.to_string())?;
assert_eq!("26984457539", d.part2()?);
Ok(())
}
#[test]
fn part1_real() {
let d = Day06::init(crate::load_input("06"));
assert_eq!("362740", d.part1());
fn part1_real() -> Result<()> {
let d = Day06::init(crate::load_input("06")?)?;
assert_eq!("362740", d.part1()?);
Ok(())
}
#[test]
fn part2_real() {
let d = Day06::init(crate::load_input("06"));
assert_eq!("1644874076764", d.part2());
fn part2_real() -> Result<()> {
let d = Day06::init(crate::load_input("06")?)?;
assert_eq!("1644874076764", d.part2()?);
Ok(())
}
#[test]
fn youri_test() -> Result<()> {
let d = Day06::init(String::from("3,4,3,1,2"))?;
assert_eq!(17614907331943978900, d.do_magic(489));
Ok(())
}
}

View File

@ -1,30 +1,31 @@
use std::collections::HashMap;
use crate::Day;
use anyhow::Result;
pub struct Day07(HashMap<i32, i32>);
impl Day for Day07 {
fn init(content: String) -> Self {
fn init(content: String) -> Result<Self> {
let mut hm = HashMap::new();
for n in &content.split(',').map(|x| x.parse().expect("This is not a number?")).collect::<Vec<_>>() {
for n in &content.split(',').map(str::parse).collect::<Result<Vec<_>, std::num::ParseIntError>>()? {
let entry = hm.entry(*n).or_insert(0);
*entry += 1;
}
Self(hm)
Ok(Self(hm))
}
fn part1(&self) -> String {
fn part1(&self) -> Result<String> {
let m = self.0.keys().copied().map(
|x| self.0.iter().map(
|(n, count)| (x - *n).abs() * (*count)
).sum::<i32>()
).min().expect("there is no min?");
).min().ok_or_else(|| anyhow::Error::msg("Could not find min"))?;
format!("{}", m)
Ok(format!("{}", m))
}
fn part2(&self) -> String {
let max = *self.0.keys().max().expect("This should have a value...");
fn part2(&self) -> Result<String> {
let max = *self.0.keys().max().ok_or_else(|| anyhow::Error::msg("Could not find max"))?;
let m = (0..=max).map(
|x| self.0.iter().map(
|(n, count)| {
@ -32,8 +33,8 @@ impl Day for Day07 {
(n * (n + 1) / 2) * (*count)
}
).sum::<i32>()
).min().expect("there is no min?");
format!("{}", m)
).min().ok_or_else(|| anyhow::Error::msg("Could not find min"))?;
Ok(format!("{}", m))
}
}
@ -41,30 +42,35 @@ impl Day for Day07 {
mod tests {
use crate::day07::Day07;
use crate::day::Day;
use anyhow::Result;
const INPUT: &str = "16,1,2,0,4,2,7,1,2,14";
#[test]
fn part1_test() {
let d = Day07::init(INPUT.to_string());
assert_eq!("37", d.part1())
fn part1_test() -> Result<()> {
let d = Day07::init(INPUT.to_string())?;
assert_eq!("37", d.part1()?);
Ok(())
}
#[test]
fn part2_test() {
let d = Day07::init(INPUT.to_string());
assert_eq!("168", d.part2())
fn part2_test() -> Result<()> {
let d = Day07::init(INPUT.to_string())?;
assert_eq!("168", d.part2()?);
Ok(())
}
#[test]
fn part1_real() {
let d = Day07::init(crate::load_input("07"));
assert_eq!("357353", d.part1())
fn part1_real() -> Result<()> {
let d = Day07::init(crate::load_input("07")?)?;
assert_eq!("357353", d.part1()?);
Ok(())
}
#[test]
fn part2_real() {
let d = Day07::init(crate::load_input("07"));
assert_eq!("104822130", d.part2())
fn part2_real() -> Result<()> {
let d = Day07::init(crate::load_input("07")?)?;
assert_eq!("104822130", d.part2()?);
Ok(())
}
}

View File

@ -9,6 +9,7 @@ use crate::day05::Day05;
use crate::day06::Day06;
use crate::day07::Day07;
use crate::day::Day;
use anyhow::Result;
mod day;
mod day01;
@ -19,22 +20,23 @@ mod day05;
mod day06;
mod day07;
fn load_input(day: &str) -> String {
read_to_string(format!("./input/day{}", day)).expect("Could not load input")
fn load_input(day: &str) -> Result<String> {
read_to_string(format!("./input/day{}", day)).map_err(|x| x.into())
}
fn run_day(days: &[Box<dyn Day>], day: usize) {
fn run_day(days: &[Box<dyn Day>], day: usize) -> Result<()> {
if let Some(d) = days.get(day - 1) {
let day_code = d;
println!("Running day {}!", day);
println!("\tPart 1: {}", d.part1());
println!("\tPart 2: {}", day_code.part2());
println!("\tPart 1: {}", d.part1()?);
println!("\tPart 2: {}", day_code.part2()?);
} else {
eprintln!("Day {} is not available!", day);
}
Ok(())
}
fn main() {
fn main() -> anyhow::Result<()> {
let matches = App::new("AOC Time!")
.version("1.0")
.author("J00LZ")
@ -52,31 +54,32 @@ fn main() {
.multiple(true))
.get_matches();
let days: Vec<Box<dyn Day>> = vec![Box::new(Day01::init(load_input("01"))),
Box::new(Day02::init(load_input("02"))),
Box::new(Day03::init(load_input("03"))),
Box::new(Day04::init(load_input("04"))),
Box::new(Day05::init(load_input("05"))),
Box::new(Day06::init(load_input("06"))),
Box::new(Day07::init(load_input("07")))];
let days: Vec<Box<dyn Day>> = vec![Box::new(Day01::init(load_input("01")?)?),
Box::new(Day02::init(load_input("02")?)?),
Box::new(Day03::init(load_input("03")?)?),
Box::new(Day04::init(load_input("04")?)?),
Box::new(Day05::init(load_input("05")?)?),
Box::new(Day06::init(load_input("06")?)?),
Box::new(Day07::init(load_input("07")?)?)];
let _verbosity = matches.occurrences_of("v");
if matches.is_present("all") {
let l = days.len();
println!("running {} days!", l);
for v in 1..=l {
run_day(&days, v);
run_day(&days, v)?;
}
} else if let Some(d) = matches.values_of("DAY") {
let d = d.map(|x| x.parse::<usize>().expect("Did not provide an int!"));
let d = d.map(str::parse);
for v in d {
run_day(&days, v);
run_day(&days, v?)?;
}
} else {
let v = chrono::Local::now();
if v.month() != 12 {
println!("This was really only meant to be used in december...");
}
run_day(&days, v.day() as usize);
run_day(&days, v.day() as usize)?;
}
Ok(())
}