~savoy/ade

3561bbd5d0eec28f64af3c7aeb40e196b6fa991a — savoy 2 years ago 952e19d feature/rust
added: CalendarError maps to Python IndexError

Signed-off-by: savoy <git@liberation.red>
1 files changed, 29 insertions(+), 4 deletions(-)

M src/dates.rs
M src/dates.rs => src/dates.rs +29 -4
@@ 27,8 27,10 @@
//! period of 2015-11-22 - 2016-01-02 instead of ending on 2015-12-26, allowing the new year to
//! start 2016-01-03.

use pyo3::exceptions::PyValueError;
use pyo3::prelude::*;
use pyo3::types::{PyDate, PyTuple};
use std::fmt;
use std::ops::Add;
use time::{macros::date, Date, Duration, Month, OffsetDateTime};



@@ 43,6 45,29 @@ pub enum CalendarError {
    MonthOutOfBounds,
}

impl std::error::Error for CalendarError {}

impl fmt::Display for CalendarError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match &self {
            CalendarError::YearOutOfBounds => write!(
                f,
                "The given year is out of range. Please choose a year between 1970 and 2099."
            ),
            CalendarError::MonthOutOfBounds => write!(
                f,
                "The given month is out of range. Please choose a month number between 1 and 12."
            ),
        }
    }
}

impl std::convert::From<CalendarError> for PyErr {
    fn from(err: CalendarError) -> PyErr {
        PyValueError::new_err(err.to_string())
    }
}

/// Type wrapper around an integer year.
#[derive(Debug)]
struct FinancialYear {


@@ 186,11 211,11 @@ impl FinancialCalendar {
    /// If the year is out of bounds of the library's range of 1970 through 2099, or the given month
    /// is not 1 through 12, `CalendarError` will be returned.
    #[new]
    pub fn new(year: u16, month: Option<u8>) -> PyResult<Self> {
    pub fn new(year: u16, month: Option<u8>) -> Result<Self, CalendarError> {
        // Unwraps are allowed as panics will propogate up to python
        let target_year = FinancialYear::from(year).unwrap();
        let target_year = FinancialYear::from(year)?;
        let target_month = match month {
            Some(m) => Some(FinancialMonth::from(m).unwrap()),
            Some(m) => Some(FinancialMonth::from(m)?),
            None => None,
        };



@@ 324,7 349,7 @@ impl FinancialCalendar {
/// In essence, it's a higher-level wrapper around `FinancialCalendar` where the user does not need
/// to input a year/month in order to get a result.
#[pyfunction]
pub fn close() -> PyResult<FinancialCalendar> {
pub fn close() -> Result<FinancialCalendar, CalendarError> {
    let now = OffsetDateTime::now_utc();
    FinancialCalendar::new(now.year() as u16, Some(convert_month_to_int(&now.month())))
}