2023-07-24 17:54:49 -04:00
use nom ::branch ::alt ;
2023-07-27 18:59:22 -04:00
use nom ::bytes ::complete ::tag ;
use nom ::character ::complete ::anychar ;
2023-07-27 19:20:28 -04:00
use nom ::character ::complete ::digit1 ;
2023-07-27 18:59:22 -04:00
use nom ::character ::complete ::one_of ;
2023-07-27 19:20:28 -04:00
use nom ::character ::complete ::space1 ;
use nom ::combinator ::opt ;
2023-07-27 18:59:22 -04:00
use nom ::combinator ::recognize ;
use nom ::combinator ::verify ;
use nom ::multi ::many_till ;
2023-07-27 19:20:28 -04:00
use nom ::sequence ::tuple ;
2023-07-24 17:54:49 -04:00
2023-08-23 00:30:26 -04:00
use super ::org_source ::OrgSource ;
2023-08-31 15:44:44 -04:00
use super ::util ::maybe_consume_object_trailing_whitespace_if_not_exiting ;
2023-07-24 17:34:07 -04:00
use super ::Context ;
use crate ::error ::Res ;
2023-07-27 18:59:22 -04:00
use crate ::parser ::util ::get_consumed ;
2023-07-24 17:34:07 -04:00
use crate ::parser ::Timestamp ;
2023-08-10 20:04:59 -04:00
#[ cfg_attr(feature = " tracing " , tracing::instrument(ret, level = " debug " )) ]
2023-08-23 00:30:26 -04:00
pub fn timestamp < ' r , ' s > (
2023-09-02 19:16:44 -04:00
context : RefContext < ' r , ' s > ,
2023-08-23 00:30:26 -04:00
input : OrgSource < ' s > ,
) -> Res < OrgSource < ' s > , Timestamp < ' s > > {
2023-07-24 17:54:49 -04:00
// TODO: This would be more efficient if we didn't throw away the parse result of the first half of an active/inactive date range timestamp if the parse fails (as in, the first thing active_date_range_timestamp parses is a active_timestamp but then we throw that away if it doesn't turn out to be a full active_date_range_timestamp despite the active_timestamp parse being completely valid). I am going with the simplest/cleanest approach for the first implementation.
alt ( (
// Order matters here. If its a date range, we need to parse the entire date range instead of just the first timestamp. If its a time range, we need to make sure thats parsed as a time range instead of as the "rest" portion of a single timestamp.
parser_with_context! ( diary_timestamp ) ( context ) ,
parser_with_context! ( active_time_range_timestamp ) ( context ) ,
parser_with_context! ( inactive_time_range_timestamp ) ( context ) ,
parser_with_context! ( active_date_range_timestamp ) ( context ) ,
parser_with_context! ( inactive_date_range_timestamp ) ( context ) ,
parser_with_context! ( active_timestamp ) ( context ) ,
parser_with_context! ( inactive_timestamp ) ( context ) ,
) ) ( input )
}
2023-08-10 20:04:59 -04:00
#[ cfg_attr(feature = " tracing " , tracing::instrument(ret, level = " debug " )) ]
2023-07-24 17:54:49 -04:00
fn diary_timestamp < ' r , ' s > (
2023-09-02 19:16:44 -04:00
context : RefContext < ' r , ' s > ,
2023-08-23 00:30:26 -04:00
input : OrgSource < ' s > ,
) -> Res < OrgSource < ' s > , Timestamp < ' s > > {
2023-07-27 18:59:22 -04:00
let ( remaining , _ ) = tag ( " <%%( " ) ( input ) ? ;
let ( remaining , _body ) = sexp ( context , remaining ) ? ;
let ( remaining , _ ) = tag ( " )> " ) ( remaining ) ? ;
2023-08-31 15:44:44 -04:00
let ( remaining , _trailing_whitespace ) =
maybe_consume_object_trailing_whitespace_if_not_exiting ( context , remaining ) ? ;
2023-07-27 18:59:22 -04:00
let source = get_consumed ( input , remaining ) ;
2023-08-23 00:30:26 -04:00
Ok ( (
remaining ,
Timestamp {
source : source . into ( ) ,
} ,
) )
2023-07-27 18:59:22 -04:00
}
2023-08-10 20:04:59 -04:00
#[ cfg_attr(feature = " tracing " , tracing::instrument(ret, level = " debug " )) ]
2023-08-23 00:30:26 -04:00
fn sexp < ' r , ' s > (
2023-09-02 19:16:44 -04:00
context : RefContext < ' r , ' s > ,
2023-08-23 00:30:26 -04:00
input : OrgSource < ' s > ,
) -> Res < OrgSource < ' s > , OrgSource < ' s > > {
2023-07-27 18:59:22 -04:00
let parser_context =
context . with_additional_node ( ContextElement ::ExitMatcherNode ( ExitMatcherNode {
2023-08-24 23:34:23 -04:00
class : ExitClass ::Gamma ,
2023-07-27 18:59:22 -04:00
exit_matcher : & sexp_end ,
} ) ) ;
let ( remaining , body ) = recognize ( verify (
many_till (
anychar ,
parser_with_context! ( exit_matcher_parser ) ( & parser_context ) ,
) ,
| ( body , _end_contents ) | ! body . is_empty ( ) ,
) ) ( input ) ? ;
Ok ( ( remaining , body ) )
}
2023-08-10 20:04:59 -04:00
#[ cfg_attr(feature = " tracing " , tracing::instrument(ret, level = " debug " )) ]
2023-08-23 00:30:26 -04:00
fn sexp_end < ' r , ' s > (
2023-09-02 19:16:44 -04:00
_context : RefContext < ' r , ' s > ,
2023-08-23 00:30:26 -04:00
input : OrgSource < ' s > ,
) -> Res < OrgSource < ' s > , OrgSource < ' s > > {
2023-07-27 18:59:22 -04:00
alt ( ( tag ( " )> " ) , recognize ( one_of ( " > \n " ) ) ) ) ( input )
2023-07-24 17:54:49 -04:00
}
2023-08-10 20:04:59 -04:00
#[ cfg_attr(feature = " tracing " , tracing::instrument(ret, level = " debug " )) ]
2023-07-24 17:54:49 -04:00
fn active_timestamp < ' r , ' s > (
2023-09-02 19:16:44 -04:00
context : RefContext < ' r , ' s > ,
2023-08-23 00:30:26 -04:00
input : OrgSource < ' s > ,
) -> Res < OrgSource < ' s > , Timestamp < ' s > > {
2023-07-27 19:20:28 -04:00
let ( remaining , _ ) = tag ( " < " ) ( input ) ? ;
let ( remaining , _date ) = date ( context , remaining ) ? ;
2023-07-27 19:52:35 -04:00
let time_context =
context . with_additional_node ( ContextElement ::ExitMatcherNode ( ExitMatcherNode {
2023-08-24 23:34:23 -04:00
class : ExitClass ::Gamma ,
2023-07-27 19:52:35 -04:00
exit_matcher : & active_time_rest_end ,
} ) ) ;
2023-07-27 19:45:57 -04:00
let ( remaining , _time ) =
2023-07-27 19:52:35 -04:00
opt ( tuple ( ( space1 , parser_with_context! ( time ) ( & time_context ) ) ) ) ( remaining ) ? ;
2023-07-27 19:45:57 -04:00
let ( remaining , _repeater ) =
opt ( tuple ( ( space1 , parser_with_context! ( repeater ) ( context ) ) ) ) ( remaining ) ? ;
let ( remaining , _warning_delay ) = opt ( tuple ( (
space1 ,
parser_with_context! ( warning_delay ) ( context ) ,
) ) ) ( remaining ) ? ;
let ( remaining , _ ) = tag ( " > " ) ( remaining ) ? ;
2023-08-31 15:44:44 -04:00
let ( remaining , _trailing_whitespace ) =
maybe_consume_object_trailing_whitespace_if_not_exiting ( context , remaining ) ? ;
2023-07-27 19:45:57 -04:00
let source = get_consumed ( input , remaining ) ;
2023-08-23 00:30:26 -04:00
Ok ( (
remaining ,
Timestamp {
source : source . into ( ) ,
} ,
) )
2023-07-24 17:54:49 -04:00
}
2023-08-10 20:04:59 -04:00
#[ cfg_attr(feature = " tracing " , tracing::instrument(ret, level = " debug " )) ]
2023-07-24 17:54:49 -04:00
fn inactive_timestamp < ' r , ' s > (
2023-09-02 19:16:44 -04:00
context : RefContext < ' r , ' s > ,
2023-08-23 00:30:26 -04:00
input : OrgSource < ' s > ,
) -> Res < OrgSource < ' s > , Timestamp < ' s > > {
2023-07-27 19:54:33 -04:00
let ( remaining , _ ) = tag ( " [ " ) ( input ) ? ;
let ( remaining , _date ) = date ( context , remaining ) ? ;
let time_context =
context . with_additional_node ( ContextElement ::ExitMatcherNode ( ExitMatcherNode {
2023-08-24 23:34:23 -04:00
class : ExitClass ::Gamma ,
2023-07-27 19:54:33 -04:00
exit_matcher : & inactive_time_rest_end ,
} ) ) ;
let ( remaining , _time ) =
opt ( tuple ( ( space1 , parser_with_context! ( time ) ( & time_context ) ) ) ) ( remaining ) ? ;
let ( remaining , _repeater ) =
opt ( tuple ( ( space1 , parser_with_context! ( repeater ) ( context ) ) ) ) ( remaining ) ? ;
let ( remaining , _warning_delay ) = opt ( tuple ( (
space1 ,
parser_with_context! ( warning_delay ) ( context ) ,
) ) ) ( remaining ) ? ;
let ( remaining , _ ) = tag ( " ] " ) ( remaining ) ? ;
2023-08-31 15:44:44 -04:00
let ( remaining , _trailing_whitespace ) =
maybe_consume_object_trailing_whitespace_if_not_exiting ( context , remaining ) ? ;
2023-07-27 19:54:33 -04:00
let source = get_consumed ( input , remaining ) ;
2023-08-23 00:30:26 -04:00
Ok ( (
remaining ,
Timestamp {
source : source . into ( ) ,
} ,
) )
2023-07-24 17:54:49 -04:00
}
2023-08-10 20:04:59 -04:00
#[ cfg_attr(feature = " tracing " , tracing::instrument(ret, level = " debug " )) ]
2023-07-24 17:54:49 -04:00
fn active_date_range_timestamp < ' r , ' s > (
2023-09-02 19:16:44 -04:00
context : RefContext < ' r , ' s > ,
2023-08-23 00:30:26 -04:00
input : OrgSource < ' s > ,
) -> Res < OrgSource < ' s > , Timestamp < ' s > > {
2023-07-27 19:59:36 -04:00
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 ) ? ;
2023-08-31 15:44:44 -04:00
let ( remaining , _trailing_whitespace ) =
maybe_consume_object_trailing_whitespace_if_not_exiting ( context , remaining ) ? ;
2023-07-27 19:59:36 -04:00
let source = get_consumed ( input , remaining ) ;
2023-08-23 00:30:26 -04:00
Ok ( (
remaining ,
Timestamp {
source : source . into ( ) ,
} ,
) )
2023-07-24 17:54:49 -04:00
}
2023-08-10 20:04:59 -04:00
#[ cfg_attr(feature = " tracing " , tracing::instrument(ret, level = " debug " )) ]
2023-07-24 17:54:49 -04:00
fn active_time_range_timestamp < ' r , ' s > (
2023-09-02 19:16:44 -04:00
context : RefContext < ' r , ' s > ,
2023-08-23 00:30:26 -04:00
input : OrgSource < ' s > ,
) -> Res < OrgSource < ' s > , Timestamp < ' s > > {
2023-07-27 20:26:56 -04:00
let ( remaining , _ ) = tag ( " < " ) ( input ) ? ;
let ( remaining , _date ) = date ( context , remaining ) ? ;
let time_context =
context . with_additional_node ( ContextElement ::ExitMatcherNode ( ExitMatcherNode {
2023-08-24 23:34:23 -04:00
class : ExitClass ::Gamma ,
2023-07-27 20:26:56 -04:00
exit_matcher : & active_time_rest_end ,
} ) ) ;
let first_time_context =
time_context . with_additional_node ( ContextElement ::ExitMatcherNode ( ExitMatcherNode {
2023-08-24 23:34:23 -04:00
class : ExitClass ::Gamma ,
2023-07-27 20:26:56 -04:00
exit_matcher : & time_range_rest_end ,
} ) ) ;
let ( remaining , _first_time ) =
tuple ( ( space1 , parser_with_context! ( time ) ( & first_time_context ) ) ) ( remaining ) ? ;
let ( remaining , _ ) = tag ( " - " ) ( remaining ) ? ;
let ( remaining , _second_time ) = parser_with_context! ( time ) ( & time_context ) ( remaining ) ? ;
let ( remaining , _repeater ) =
opt ( tuple ( ( space1 , parser_with_context! ( repeater ) ( context ) ) ) ) ( remaining ) ? ;
let ( remaining , _warning_delay ) = opt ( tuple ( (
space1 ,
parser_with_context! ( warning_delay ) ( context ) ,
) ) ) ( remaining ) ? ;
let ( remaining , _ ) = tag ( " > " ) ( remaining ) ? ;
2023-08-31 15:44:44 -04:00
let ( remaining , _trailing_whitespace ) =
maybe_consume_object_trailing_whitespace_if_not_exiting ( context , remaining ) ? ;
2023-07-27 20:26:56 -04:00
let source = get_consumed ( input , remaining ) ;
2023-08-23 00:30:26 -04:00
Ok ( (
remaining ,
Timestamp {
source : source . into ( ) ,
} ,
) )
2023-07-24 17:54:49 -04:00
}
2023-08-10 20:04:59 -04:00
#[ cfg_attr(feature = " tracing " , tracing::instrument(ret, level = " debug " )) ]
2023-07-24 17:54:49 -04:00
fn inactive_date_range_timestamp < ' r , ' s > (
2023-09-02 19:16:44 -04:00
context : RefContext < ' r , ' s > ,
2023-08-23 00:30:26 -04:00
input : OrgSource < ' s > ,
) -> Res < OrgSource < ' s > , Timestamp < ' s > > {
2023-07-27 19:59:36 -04:00
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 ) ? ;
2023-08-31 15:44:44 -04:00
let ( remaining , _trailing_whitespace ) =
maybe_consume_object_trailing_whitespace_if_not_exiting ( context , remaining ) ? ;
2023-07-27 19:59:36 -04:00
let source = get_consumed ( input , remaining ) ;
2023-08-23 00:30:26 -04:00
Ok ( (
remaining ,
Timestamp {
source : source . into ( ) ,
} ,
) )
2023-07-24 17:54:49 -04:00
}
2023-08-10 20:04:59 -04:00
#[ cfg_attr(feature = " tracing " , tracing::instrument(ret, level = " debug " )) ]
2023-07-24 17:54:49 -04:00
fn inactive_time_range_timestamp < ' r , ' s > (
2023-09-02 19:16:44 -04:00
context : RefContext < ' r , ' s > ,
2023-08-23 00:30:26 -04:00
input : OrgSource < ' s > ,
) -> Res < OrgSource < ' s > , Timestamp < ' s > > {
2023-07-27 20:26:56 -04:00
let ( remaining , _ ) = tag ( " [ " ) ( input ) ? ;
let ( remaining , _date ) = date ( context , remaining ) ? ;
let time_context =
context . with_additional_node ( ContextElement ::ExitMatcherNode ( ExitMatcherNode {
2023-08-24 23:34:23 -04:00
class : ExitClass ::Gamma ,
2023-07-27 20:26:56 -04:00
exit_matcher : & inactive_time_rest_end ,
} ) ) ;
let first_time_context =
time_context . with_additional_node ( ContextElement ::ExitMatcherNode ( ExitMatcherNode {
2023-08-24 23:34:23 -04:00
class : ExitClass ::Gamma ,
2023-07-27 20:26:56 -04:00
exit_matcher : & time_range_rest_end ,
} ) ) ;
let ( remaining , _first_time ) =
tuple ( ( space1 , parser_with_context! ( time ) ( & first_time_context ) ) ) ( remaining ) ? ;
let ( remaining , _ ) = tag ( " - " ) ( remaining ) ? ;
let ( remaining , _second_time ) = parser_with_context! ( time ) ( & time_context ) ( remaining ) ? ;
let ( remaining , _repeater ) =
opt ( tuple ( ( space1 , parser_with_context! ( repeater ) ( context ) ) ) ) ( remaining ) ? ;
let ( remaining , _warning_delay ) = opt ( tuple ( (
space1 ,
parser_with_context! ( warning_delay ) ( context ) ,
) ) ) ( remaining ) ? ;
let ( remaining , _ ) = tag ( " ] " ) ( remaining ) ? ;
2023-08-31 15:44:44 -04:00
let ( remaining , _trailing_whitespace ) =
maybe_consume_object_trailing_whitespace_if_not_exiting ( context , remaining ) ? ;
2023-07-27 20:26:56 -04:00
let source = get_consumed ( input , remaining ) ;
2023-08-23 00:30:26 -04:00
Ok ( (
remaining ,
Timestamp {
source : source . into ( ) ,
} ,
) )
2023-07-24 17:34:07 -04:00
}
2023-07-27 19:20:28 -04:00
2023-08-10 20:04:59 -04:00
#[ cfg_attr(feature = " tracing " , tracing::instrument(ret, level = " debug " )) ]
2023-08-23 00:30:26 -04:00
fn date < ' r , ' s > (
2023-09-02 19:16:44 -04:00
context : RefContext < ' r , ' s > ,
2023-08-23 00:30:26 -04:00
input : OrgSource < ' s > ,
) -> Res < OrgSource < ' s > , OrgSource < ' s > > {
let ( remaining , _year ) = verify ( digit1 , | year : & OrgSource < '_ > | year . len ( ) = = 4 ) ( input ) ? ;
2023-07-27 19:20:28 -04:00
let ( remaining , _ ) = tag ( " - " ) ( remaining ) ? ;
2023-08-23 00:30:26 -04:00
let ( remaining , _month ) = verify ( digit1 , | month : & OrgSource < '_ > | month . len ( ) = = 2 ) ( remaining ) ? ;
2023-07-27 19:20:28 -04:00
let ( remaining , _ ) = tag ( " - " ) ( remaining ) ? ;
2023-08-23 00:30:26 -04:00
let ( remaining , _day_of_month ) = verify ( digit1 , | day_of_month : & OrgSource < '_ > | {
day_of_month . len ( ) = = 2
} ) ( remaining ) ? ;
2023-07-27 19:20:28 -04:00
let ( remaining , _dayname ) =
opt ( tuple ( ( space1 , parser_with_context! ( dayname ) ( context ) ) ) ) ( remaining ) ? ;
let source = get_consumed ( input , remaining ) ;
Ok ( ( remaining , source ) )
}
2023-08-10 20:04:59 -04:00
#[ cfg_attr(feature = " tracing " , tracing::instrument(ret, level = " debug " )) ]
2023-08-23 00:30:26 -04:00
fn dayname < ' r , ' s > (
2023-09-02 19:16:44 -04:00
context : RefContext < ' r , ' s > ,
2023-08-23 00:30:26 -04:00
input : OrgSource < ' s > ,
) -> Res < OrgSource < ' s > , OrgSource < ' s > > {
2023-07-27 19:20:28 -04:00
let parser_context =
context . with_additional_node ( ContextElement ::ExitMatcherNode ( ExitMatcherNode {
2023-08-24 23:34:23 -04:00
class : ExitClass ::Gamma ,
2023-07-27 19:20:28 -04:00
exit_matcher : & dayname_end ,
} ) ) ;
let ( remaining , body ) = recognize ( verify (
many_till (
anychar ,
parser_with_context! ( exit_matcher_parser ) ( & parser_context ) ,
) ,
| ( body , _end_contents ) | ! body . is_empty ( ) ,
) ) ( input ) ? ;
Ok ( ( remaining , body ) )
}
2023-08-10 20:04:59 -04:00
#[ cfg_attr(feature = " tracing " , tracing::instrument(ret, level = " debug " )) ]
2023-08-23 00:30:26 -04:00
fn dayname_end < ' r , ' s > (
2023-09-02 19:16:44 -04:00
_context : RefContext < ' r , ' s > ,
2023-08-23 00:30:26 -04:00
input : OrgSource < ' s > ,
) -> Res < OrgSource < ' s > , OrgSource < ' s > > {
2023-07-27 19:20:28 -04:00
recognize ( verify ( anychar , | c | {
c . is_whitespace ( ) | | " +-]>0123456789 \n " . contains ( * c )
} ) ) ( input )
}
2023-07-27 19:45:57 -04:00
2023-08-10 20:04:59 -04:00
#[ cfg_attr(feature = " tracing " , tracing::instrument(ret, level = " debug " )) ]
2023-08-23 00:30:26 -04:00
fn time < ' r , ' s > (
2023-09-02 19:16:44 -04:00
context : RefContext < ' r , ' s > ,
2023-08-23 00:30:26 -04:00
input : OrgSource < ' s > ,
) -> Res < OrgSource < ' s > , OrgSource < ' s > > {
let ( remaining , _hour ) = verify ( digit1 , | hour : & OrgSource < '_ > | {
hour . len ( ) > = 1 & & hour . len ( ) < = 2
} ) ( input ) ? ;
2023-07-27 19:45:57 -04:00
let ( remaining , _ ) = tag ( " : " ) ( remaining ) ? ;
2023-08-23 00:30:26 -04:00
let ( remaining , _minute ) =
verify ( digit1 , | minute : & OrgSource < '_ > | minute . len ( ) = = 2 ) ( remaining ) ? ;
2023-07-27 19:52:35 -04:00
let ( remaining , _time_rest ) = opt ( parser_with_context! ( time_rest ) ( context ) ) ( remaining ) ? ;
2023-07-27 19:45:57 -04:00
let source = get_consumed ( input , remaining ) ;
Ok ( ( remaining , source ) )
}
2023-08-10 20:04:59 -04:00
#[ cfg_attr(feature = " tracing " , tracing::instrument(ret, level = " debug " )) ]
2023-08-23 00:30:26 -04:00
fn time_rest < ' r , ' s > (
2023-09-02 19:16:44 -04:00
context : RefContext < ' r , ' s > ,
2023-08-23 00:30:26 -04:00
input : OrgSource < ' s > ,
) -> Res < OrgSource < ' s > , OrgSource < ' s > > {
2023-07-27 19:45:57 -04:00
let ( remaining , body ) = recognize ( verify (
2023-07-27 19:52:35 -04:00
many_till ( anychar , parser_with_context! ( exit_matcher_parser ) ( context ) ) ,
2023-07-27 19:45:57 -04:00
| ( body , _end_contents ) | ! body . is_empty ( ) ,
) ) ( input ) ? ;
Ok ( ( remaining , body ) )
}
2023-08-10 20:04:59 -04:00
#[ cfg_attr(feature = " tracing " , tracing::instrument(ret, level = " debug " )) ]
2023-08-23 00:30:26 -04:00
fn active_time_rest_end < ' r , ' s > (
2023-09-02 19:16:44 -04:00
context : RefContext < ' r , ' s > ,
2023-08-23 00:30:26 -04:00
input : OrgSource < ' s > ,
) -> Res < OrgSource < ' s > , OrgSource < ' s > > {
2023-07-27 19:45:57 -04:00
alt ( (
recognize ( verify ( anychar , | c | " > \n " . contains ( * c ) ) ) ,
2023-07-27 20:39:13 -04:00
recognize ( tuple ( ( space1 , parser_with_context! ( repeater ) ( context ) ) ) ) ,
recognize ( tuple ( (
space1 ,
parser_with_context! ( warning_delay ) ( context ) ,
) ) ) ,
2023-07-27 19:45:57 -04:00
) ) ( input )
}
2023-08-10 20:04:59 -04:00
#[ cfg_attr(feature = " tracing " , tracing::instrument(ret, level = " debug " )) ]
2023-07-27 19:54:33 -04:00
fn inactive_time_rest_end < ' r , ' s > (
2023-09-02 19:16:44 -04:00
context : RefContext < ' r , ' s > ,
2023-08-23 00:30:26 -04:00
input : OrgSource < ' s > ,
) -> Res < OrgSource < ' s > , OrgSource < ' s > > {
2023-07-27 19:54:33 -04:00
alt ( (
recognize ( verify ( anychar , | c | " ] \n " . contains ( * c ) ) ) ,
2023-07-27 20:39:13 -04:00
recognize ( tuple ( ( space1 , parser_with_context! ( repeater ) ( context ) ) ) ) ,
recognize ( tuple ( (
space1 ,
parser_with_context! ( warning_delay ) ( context ) ,
) ) ) ,
2023-07-27 19:54:33 -04:00
) ) ( input )
}
2023-08-10 20:04:59 -04:00
#[ cfg_attr(feature = " tracing " , tracing::instrument(ret, level = " debug " )) ]
2023-08-23 00:30:26 -04:00
fn time_range_rest_end < ' r , ' s > (
2023-09-02 19:16:44 -04:00
context : RefContext < ' r , ' s > ,
2023-08-23 00:30:26 -04:00
input : OrgSource < ' s > ,
) -> Res < OrgSource < ' s > , OrgSource < ' s > > {
2023-07-27 20:26:56 -04:00
// We pop off the most recent context element to get a context tree with just the active/inactive_time_rest_end exit matcher (removing this function from the exit matcher chain) because the 2nd time in the range does not end when a "-TIME" pattern is found.
let parent_node = context . iter ( ) . next ( ) . expect ( " Two context elements are added to the tree when adding this exit matcher, so it should be impossible for this to return None. " ) ;
let parent_tree = ContextTree ::branch_from ( parent_node ) ;
let exit_contents =
recognize ( tuple ( ( tag ( " - " ) , parser_with_context! ( time ) ( & parent_tree ) ) ) ) ( input ) ;
exit_contents
}
2023-08-10 20:04:59 -04:00
#[ cfg_attr(feature = " tracing " , tracing::instrument(ret, level = " debug " )) ]
2023-08-23 00:30:26 -04:00
fn repeater < ' r , ' s > (
2023-09-02 19:16:44 -04:00
_context : RefContext < ' r , ' s > ,
2023-08-23 00:30:26 -04:00
input : OrgSource < ' s > ,
) -> Res < OrgSource < ' s > , OrgSource < ' s > > {
2023-07-27 19:45:57 -04:00
// + for cumulative type
// ++ for catch-up type
// .+ for restart type
let ( remaining , _mark ) = alt ( ( tag ( " ++ " ) , tag ( " + " ) , tag ( " .+ " ) ) ) ( input ) ? ;
let ( remaining , _value ) = digit1 ( remaining ) ? ;
// h = hour, d = day, w = week, m = month, y = year
let ( remaining , _unit ) = recognize ( one_of ( " hdwmy " ) ) ( remaining ) ? ;
let source = get_consumed ( input , remaining ) ;
Ok ( ( remaining , source ) )
}
2023-08-10 20:04:59 -04:00
#[ cfg_attr(feature = " tracing " , tracing::instrument(ret, level = " debug " )) ]
2023-08-23 00:30:26 -04:00
fn warning_delay < ' r , ' s > (
2023-09-02 19:16:44 -04:00
_context : RefContext < ' r , ' s > ,
2023-08-23 00:30:26 -04:00
input : OrgSource < ' s > ,
) -> Res < OrgSource < ' s > , OrgSource < ' s > > {
2023-07-27 19:45:57 -04:00
// - for all type
// -- for first type
let ( remaining , _mark ) = alt ( ( tag ( " -- " ) , tag ( " - " ) ) ) ( input ) ? ;
let ( remaining , _value ) = digit1 ( remaining ) ? ;
// h = hour, d = day, w = week, m = month, y = year
let ( remaining , _unit ) = recognize ( one_of ( " hdwmy " ) ) ( remaining ) ? ;
let source = get_consumed ( input , remaining ) ;
Ok ( ( remaining , source ) )
}