Compare date start/end.
This commit is contained in:
		
							parent
							
								
									c55fae86f8
								
							
						
					
					
						commit
						a8a34e2d9c
					
				@ -24,6 +24,9 @@ use crate::types::Clock;
 | 
			
		||||
use crate::types::Code;
 | 
			
		||||
use crate::types::Comment;
 | 
			
		||||
use crate::types::CommentBlock;
 | 
			
		||||
use crate::types::Date;
 | 
			
		||||
use crate::types::DayOfMonth;
 | 
			
		||||
use crate::types::DayOfMonthInner;
 | 
			
		||||
use crate::types::DiarySexp;
 | 
			
		||||
use crate::types::Document;
 | 
			
		||||
use crate::types::DocumentElement;
 | 
			
		||||
@ -47,6 +50,8 @@ use crate::types::Keyword;
 | 
			
		||||
use crate::types::LatexEnvironment;
 | 
			
		||||
use crate::types::LatexFragment;
 | 
			
		||||
use crate::types::LineBreak;
 | 
			
		||||
use crate::types::Month;
 | 
			
		||||
use crate::types::MonthInner;
 | 
			
		||||
use crate::types::NodeProperty;
 | 
			
		||||
use crate::types::OrgMacro;
 | 
			
		||||
use crate::types::Paragraph;
 | 
			
		||||
@ -81,6 +86,8 @@ use crate::types::TodoKeywordType;
 | 
			
		||||
use crate::types::Underline;
 | 
			
		||||
use crate::types::Verbatim;
 | 
			
		||||
use crate::types::VerseBlock;
 | 
			
		||||
use crate::types::Year;
 | 
			
		||||
use crate::types::YearInner;
 | 
			
		||||
 | 
			
		||||
#[derive(Debug)]
 | 
			
		||||
pub enum DiffEntry<'b, 's> {
 | 
			
		||||
@ -2165,21 +2172,76 @@ fn compare_timestamp<'b, 's>(
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Compare start
 | 
			
		||||
    let year_start: Option<u16> = get_property_unquoted_atom(emacs, ":year-start")?
 | 
			
		||||
        .map(|val| val.parse())
 | 
			
		||||
        .map_or(Ok(None), |r| r.map(Some))?;
 | 
			
		||||
    let month_start: Option<u8> = get_property_unquoted_atom(emacs, ":month-start")?
 | 
			
		||||
        .map(|val| val.parse())
 | 
			
		||||
        .map_or(Ok(None), |r| r.map(Some))?;
 | 
			
		||||
    let day_of_month_start: Option<u8> = get_property_unquoted_atom(emacs, ":day-start")?
 | 
			
		||||
        .map(|val| val.parse())
 | 
			
		||||
        .map_or(Ok(None), |r| r.map(Some))?;
 | 
			
		||||
 | 
			
		||||
    let year_end = get_property_numeric::<u16>(emacs, ":year-end")?;
 | 
			
		||||
    let year_start: Option<YearInner> = get_property_numeric(emacs, ":year-start")?;
 | 
			
		||||
    let month_start: Option<MonthInner> = get_property_numeric(emacs, ":month-start")?;
 | 
			
		||||
    let day_of_month_start: Option<DayOfMonthInner> = get_property_numeric(emacs, ":day-start")?;
 | 
			
		||||
    let rust_year_start = rust.start.as_ref().map(Date::get_year).map(Year::get_value);
 | 
			
		||||
    let rust_month_start = rust
 | 
			
		||||
        .start
 | 
			
		||||
        .as_ref()
 | 
			
		||||
        .map(Date::get_month)
 | 
			
		||||
        .map(Month::get_value);
 | 
			
		||||
    let rust_day_of_month_start = rust
 | 
			
		||||
        .start
 | 
			
		||||
        .as_ref()
 | 
			
		||||
        .map(Date::get_day_of_month)
 | 
			
		||||
        .map(DayOfMonth::get_value);
 | 
			
		||||
    if year_start != rust_year_start {
 | 
			
		||||
        this_status = DiffStatus::Bad;
 | 
			
		||||
        message = Some(format!(
 | 
			
		||||
            "year start mismatch (emacs != rust) {:?} != {:?}",
 | 
			
		||||
            year_start, rust_year_start
 | 
			
		||||
        ));
 | 
			
		||||
    }
 | 
			
		||||
    if month_start != rust_month_start {
 | 
			
		||||
        this_status = DiffStatus::Bad;
 | 
			
		||||
        message = Some(format!(
 | 
			
		||||
            "month start mismatch (emacs != rust) {:?} != {:?}",
 | 
			
		||||
            month_start, rust_month_start
 | 
			
		||||
        ));
 | 
			
		||||
    }
 | 
			
		||||
    if day_of_month_start != rust_day_of_month_start {
 | 
			
		||||
        this_status = DiffStatus::Bad;
 | 
			
		||||
        message = Some(format!(
 | 
			
		||||
            "day of month start mismatch (emacs != rust) {:?} != {:?}",
 | 
			
		||||
            day_of_month_start, rust_day_of_month_start
 | 
			
		||||
        ));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Compare end
 | 
			
		||||
    let year_end: Option<YearInner> = get_property_numeric(emacs, ":year-end")?;
 | 
			
		||||
    let month_end: Option<MonthInner> = get_property_numeric(emacs, ":month-end")?;
 | 
			
		||||
    let day_of_month_end: Option<DayOfMonthInner> = get_property_numeric(emacs, ":day-end")?;
 | 
			
		||||
    let rust_year_end = rust.end.as_ref().map(Date::get_year).map(Year::get_value);
 | 
			
		||||
    let rust_month_end = rust.end.as_ref().map(Date::get_month).map(Month::get_value);
 | 
			
		||||
    let rust_day_of_month_end = rust
 | 
			
		||||
        .end
 | 
			
		||||
        .as_ref()
 | 
			
		||||
        .map(Date::get_day_of_month)
 | 
			
		||||
        .map(DayOfMonth::get_value);
 | 
			
		||||
    if year_end != rust_year_end {
 | 
			
		||||
        this_status = DiffStatus::Bad;
 | 
			
		||||
        message = Some(format!(
 | 
			
		||||
            "year end mismatch (emacs != rust) {:?} != {:?}",
 | 
			
		||||
            year_end, rust_year_end
 | 
			
		||||
        ));
 | 
			
		||||
    }
 | 
			
		||||
    if month_end != rust_month_end {
 | 
			
		||||
        this_status = DiffStatus::Bad;
 | 
			
		||||
        message = Some(format!(
 | 
			
		||||
            "month end mismatch (emacs != rust) {:?} != {:?}",
 | 
			
		||||
            month_end, rust_month_end
 | 
			
		||||
        ));
 | 
			
		||||
    }
 | 
			
		||||
    if day_of_month_end != rust_day_of_month_end {
 | 
			
		||||
        this_status = DiffStatus::Bad;
 | 
			
		||||
        message = Some(format!(
 | 
			
		||||
            "day of month end mismatch (emacs != rust) {:?} != {:?}",
 | 
			
		||||
            day_of_month_end, rust_day_of_month_end
 | 
			
		||||
        ));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // TODO: Compare :year-start :month-start :day-start :hour-start :minute-start :year-end :month-end :day-end :hour-end :minute-end :repeater-type :repeater-value :repeater-unit :warning-type :warning-value :warning-unit
 | 
			
		||||
    // TODO: Compare :hour-start :minute-start :hour-end :minute-end :repeater-type :repeater-value :repeater-unit :warning-type :warning-value :warning-unit
 | 
			
		||||
    //
 | 
			
		||||
    // :type unquoted atom either diary, active, inactive, active-range, or inactive-range.
 | 
			
		||||
    // :range-type unquoted atom either nil, daterange
 | 
			
		||||
 | 
			
		||||
@ -248,11 +248,11 @@ where
 | 
			
		||||
    <N as FromStr>::Err: std::error::Error,
 | 
			
		||||
    <N as FromStr>::Err: 's,
 | 
			
		||||
{
 | 
			
		||||
    let foo = get_property(emacs, key)?
 | 
			
		||||
    let unparsed_string = get_property(emacs, key)?
 | 
			
		||||
        .map(Token::as_atom)
 | 
			
		||||
        .map_or(Ok(None), |r| r.map(Some))?;
 | 
			
		||||
    let bar = foo
 | 
			
		||||
    let parsed_number = unparsed_string
 | 
			
		||||
        .map(|val| val.parse::<N>())
 | 
			
		||||
        .map_or(Ok(None), |r| r.map(Some))?;
 | 
			
		||||
    Ok(bar)
 | 
			
		||||
    Ok(parsed_number)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -133,8 +133,8 @@ fn active_timestamp<'b, 'g, 'r, 's>(
 | 
			
		||||
            source: source.into(),
 | 
			
		||||
            timestamp_type: TimestampType::Active,
 | 
			
		||||
            range_type: TimestampRangeType::None,
 | 
			
		||||
            start: Some(start),
 | 
			
		||||
            end: None,
 | 
			
		||||
            start: Some(start.clone()),
 | 
			
		||||
            end: Some(start),
 | 
			
		||||
        },
 | 
			
		||||
    ))
 | 
			
		||||
}
 | 
			
		||||
@ -171,8 +171,8 @@ fn inactive_timestamp<'b, 'g, 'r, 's>(
 | 
			
		||||
            source: source.into(),
 | 
			
		||||
            timestamp_type: TimestampType::Inactive,
 | 
			
		||||
            range_type: TimestampRangeType::None,
 | 
			
		||||
            start: Some(start),
 | 
			
		||||
            end: None,
 | 
			
		||||
            start: Some(start.clone()),
 | 
			
		||||
            end: Some(start),
 | 
			
		||||
        },
 | 
			
		||||
    ))
 | 
			
		||||
}
 | 
			
		||||
@ -182,10 +182,10 @@ fn active_date_range_timestamp<'b, 'g, 'r, 's>(
 | 
			
		||||
    context: RefContext<'b, 'g, 'r, 's>,
 | 
			
		||||
    input: OrgSource<'s>,
 | 
			
		||||
) -> Res<OrgSource<'s>, Timestamp<'s>> {
 | 
			
		||||
    let (remaining, _first_timestamp) = active_timestamp(context, input)?;
 | 
			
		||||
    let (remaining, first_timestamp) = active_timestamp(context, input)?;
 | 
			
		||||
    // TODO: Does the space0 at the end of the active/inactive timestamp parsers cause this to be incorrect? I could use a look-behind to make sure the preceding character is not whitespace
 | 
			
		||||
    let (remaining, _separator) = tag("--")(remaining)?;
 | 
			
		||||
    let (remaining, _second_timestamp) = active_timestamp(context, remaining)?;
 | 
			
		||||
    let (remaining, second_timestamp) = active_timestamp(context, remaining)?;
 | 
			
		||||
 | 
			
		||||
    let (remaining, _trailing_whitespace) =
 | 
			
		||||
        maybe_consume_object_trailing_whitespace_if_not_exiting(context, remaining)?;
 | 
			
		||||
@ -197,8 +197,8 @@ fn active_date_range_timestamp<'b, 'g, 'r, 's>(
 | 
			
		||||
            source: source.into(),
 | 
			
		||||
            timestamp_type: TimestampType::ActiveRange,
 | 
			
		||||
            range_type: TimestampRangeType::DateRange,
 | 
			
		||||
            start: None, // TODO
 | 
			
		||||
            end: None,   // TODO
 | 
			
		||||
            start: first_timestamp.start,
 | 
			
		||||
            end: second_timestamp.end,
 | 
			
		||||
        },
 | 
			
		||||
    ))
 | 
			
		||||
}
 | 
			
		||||
@ -209,7 +209,7 @@ fn active_time_range_timestamp<'b, 'g, 'r, 's>(
 | 
			
		||||
    input: OrgSource<'s>,
 | 
			
		||||
) -> Res<OrgSource<'s>, Timestamp<'s>> {
 | 
			
		||||
    let (remaining, _) = tag("<")(input)?;
 | 
			
		||||
    let (remaining, _date) = date(context, remaining)?;
 | 
			
		||||
    let (remaining, start_date) = date(context, remaining)?;
 | 
			
		||||
    let time_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
 | 
			
		||||
        class: ExitClass::Gamma,
 | 
			
		||||
        exit_matcher: &active_time_rest_end,
 | 
			
		||||
@ -242,8 +242,8 @@ fn active_time_range_timestamp<'b, 'g, 'r, 's>(
 | 
			
		||||
            source: source.into(),
 | 
			
		||||
            timestamp_type: TimestampType::Active,
 | 
			
		||||
            range_type: TimestampRangeType::None,
 | 
			
		||||
            start: None, // TODO
 | 
			
		||||
            end: None,   // TODO
 | 
			
		||||
            start: Some(start_date.clone()),
 | 
			
		||||
            end: Some(start_date),
 | 
			
		||||
        },
 | 
			
		||||
    ))
 | 
			
		||||
}
 | 
			
		||||
@ -253,10 +253,10 @@ fn inactive_date_range_timestamp<'b, 'g, 'r, 's>(
 | 
			
		||||
    context: RefContext<'b, 'g, 'r, 's>,
 | 
			
		||||
    input: OrgSource<'s>,
 | 
			
		||||
) -> Res<OrgSource<'s>, Timestamp<'s>> {
 | 
			
		||||
    let (remaining, _first_timestamp) = inactive_timestamp(context, input)?;
 | 
			
		||||
    let (remaining, first_timestamp) = inactive_timestamp(context, input)?;
 | 
			
		||||
    // TODO: Does the space0 at the end of the active/inactive timestamp parsers cause this to be incorrect? I could use a look-behind to make sure the preceding character is not whitespace
 | 
			
		||||
    let (remaining, _separator) = tag("--")(remaining)?;
 | 
			
		||||
    let (remaining, _second_timestamp) = inactive_timestamp(context, remaining)?;
 | 
			
		||||
    let (remaining, second_timestamp) = inactive_timestamp(context, remaining)?;
 | 
			
		||||
 | 
			
		||||
    let (remaining, _trailing_whitespace) =
 | 
			
		||||
        maybe_consume_object_trailing_whitespace_if_not_exiting(context, remaining)?;
 | 
			
		||||
@ -269,8 +269,8 @@ fn inactive_date_range_timestamp<'b, 'g, 'r, 's>(
 | 
			
		||||
 | 
			
		||||
            timestamp_type: TimestampType::InactiveRange,
 | 
			
		||||
            range_type: TimestampRangeType::DateRange,
 | 
			
		||||
            start: None, // TODO
 | 
			
		||||
            end: None,   // TODO
 | 
			
		||||
            start: first_timestamp.start,
 | 
			
		||||
            end: second_timestamp.end,
 | 
			
		||||
        },
 | 
			
		||||
    ))
 | 
			
		||||
}
 | 
			
		||||
@ -281,7 +281,7 @@ fn inactive_time_range_timestamp<'b, 'g, 'r, 's>(
 | 
			
		||||
    input: OrgSource<'s>,
 | 
			
		||||
) -> Res<OrgSource<'s>, Timestamp<'s>> {
 | 
			
		||||
    let (remaining, _) = tag("[")(input)?;
 | 
			
		||||
    let (remaining, _date) = date(context, remaining)?;
 | 
			
		||||
    let (remaining, start_date) = date(context, remaining)?;
 | 
			
		||||
    let time_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
 | 
			
		||||
        class: ExitClass::Gamma,
 | 
			
		||||
        exit_matcher: &inactive_time_rest_end,
 | 
			
		||||
@ -314,8 +314,8 @@ fn inactive_time_range_timestamp<'b, 'g, 'r, 's>(
 | 
			
		||||
            source: source.into(),
 | 
			
		||||
            timestamp_type: TimestampType::Inactive,
 | 
			
		||||
            range_type: TimestampRangeType::None,
 | 
			
		||||
            start: None, // TODO
 | 
			
		||||
            end: None,   // TODO
 | 
			
		||||
            start: Some(start_date.clone()),
 | 
			
		||||
            end: Some(start_date),
 | 
			
		||||
        },
 | 
			
		||||
    ))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -56,6 +56,7 @@ pub use object::CitationReference;
 | 
			
		||||
pub use object::Code;
 | 
			
		||||
pub use object::Date;
 | 
			
		||||
pub use object::DayOfMonth;
 | 
			
		||||
pub use object::DayOfMonthInner;
 | 
			
		||||
pub use object::Entity;
 | 
			
		||||
pub use object::ExportSnippet;
 | 
			
		||||
pub use object::FootnoteReference;
 | 
			
		||||
@ -65,6 +66,7 @@ pub use object::Italic;
 | 
			
		||||
pub use object::LatexFragment;
 | 
			
		||||
pub use object::LineBreak;
 | 
			
		||||
pub use object::Month;
 | 
			
		||||
pub use object::MonthInner;
 | 
			
		||||
pub use object::Object;
 | 
			
		||||
pub use object::OrgMacro;
 | 
			
		||||
pub use object::PlainLink;
 | 
			
		||||
@ -83,5 +85,6 @@ pub use object::TimestampType;
 | 
			
		||||
pub use object::Underline;
 | 
			
		||||
pub use object::Verbatim;
 | 
			
		||||
pub use object::Year;
 | 
			
		||||
pub use object::YearInner;
 | 
			
		||||
pub(crate) use source::SetSource;
 | 
			
		||||
pub use standard_properties::StandardProperties;
 | 
			
		||||
 | 
			
		||||
@ -206,23 +206,27 @@ pub enum TimestampRangeType {
 | 
			
		||||
    DateRange,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, PartialEq)]
 | 
			
		||||
pub struct Year(u16);
 | 
			
		||||
pub type YearInner = u16;
 | 
			
		||||
pub type MonthInner = u8;
 | 
			
		||||
pub type DayOfMonthInner = u8;
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, PartialEq)]
 | 
			
		||||
pub struct Month(u8);
 | 
			
		||||
#[derive(Debug, PartialEq, Clone)]
 | 
			
		||||
pub struct Year(YearInner);
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, PartialEq)]
 | 
			
		||||
pub struct DayOfMonth(u8);
 | 
			
		||||
#[derive(Debug, PartialEq, Clone)]
 | 
			
		||||
pub struct Month(MonthInner);
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, PartialEq, Clone)]
 | 
			
		||||
pub struct DayOfMonth(DayOfMonthInner);
 | 
			
		||||
 | 
			
		||||
impl Year {
 | 
			
		||||
    // TODO: Make a real error type instead of a boxed any error.
 | 
			
		||||
    pub fn new<'s>(source: &'s str) -> Result<Self, Box<dyn std::error::Error>> {
 | 
			
		||||
        let year = source.parse::<u16>()?;
 | 
			
		||||
        let year = source.parse::<YearInner>()?;
 | 
			
		||||
        Ok(Year(year))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn get_value(&self) -> u16 {
 | 
			
		||||
    pub fn get_value(&self) -> YearInner {
 | 
			
		||||
        self.0
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -230,14 +234,14 @@ impl Year {
 | 
			
		||||
impl Month {
 | 
			
		||||
    // TODO: Make a real error type instead of a boxed any error.
 | 
			
		||||
    pub fn new<'s>(source: &'s str) -> Result<Self, Box<dyn std::error::Error>> {
 | 
			
		||||
        let month = source.parse::<u8>()?;
 | 
			
		||||
        let month = source.parse::<MonthInner>()?;
 | 
			
		||||
        if month < 1 || month > 12 {
 | 
			
		||||
            Err("Month exceeds possible range.")?;
 | 
			
		||||
        }
 | 
			
		||||
        Ok(Month(month))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn get_value(&self) -> u8 {
 | 
			
		||||
    pub fn get_value(&self) -> MonthInner {
 | 
			
		||||
        self.0
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -245,19 +249,19 @@ impl Month {
 | 
			
		||||
impl DayOfMonth {
 | 
			
		||||
    // TODO: Make a real error type instead of a boxed any error.
 | 
			
		||||
    pub fn new<'s>(source: &'s str) -> Result<Self, Box<dyn std::error::Error>> {
 | 
			
		||||
        let day_of_month = source.parse::<u8>()?;
 | 
			
		||||
        let day_of_month = source.parse::<DayOfMonthInner>()?;
 | 
			
		||||
        if day_of_month < 1 || day_of_month > 31 {
 | 
			
		||||
            Err("Day of month exceeds possible range.")?;
 | 
			
		||||
        }
 | 
			
		||||
        Ok(DayOfMonth(day_of_month))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn get_value(&self) -> u8 {
 | 
			
		||||
    pub fn get_value(&self) -> DayOfMonthInner {
 | 
			
		||||
        self.0
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, PartialEq)]
 | 
			
		||||
#[derive(Debug, PartialEq, Clone)]
 | 
			
		||||
pub struct Date<'s> {
 | 
			
		||||
    year: Year,
 | 
			
		||||
    month: Month,
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user