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 ;
use nom ::character ::complete ::one_of ;
use nom ::character ::complete ::space0 ;
use nom ::combinator ::recognize ;
use nom ::combinator ::verify ;
use nom ::multi ::many_till ;
2023-07-24 17:54:49 -04:00
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 ::exiting ::ExitClass ;
use crate ::parser ::parser_context ::ContextElement ;
use crate ::parser ::parser_context ::ExitMatcherNode ;
2023-07-24 17:54:49 -04:00
use crate ::parser ::parser_with_context ::parser_with_context ;
2023-07-27 18:59:22 -04:00
use crate ::parser ::util ::exit_matcher_parser ;
use crate ::parser ::util ::get_consumed ;
2023-07-24 17:34:07 -04:00
use crate ::parser ::util ::not_yet_implemented ;
use crate ::parser ::Timestamp ;
#[ tracing::instrument(ret, level = " debug " ) ]
pub fn timestamp < ' r , ' s > ( context : Context < ' r , ' s > , input : & ' s str ) -> Res < & ' s str , 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 )
}
#[ tracing::instrument(ret, level = " debug " ) ]
fn diary_timestamp < ' r , ' s > (
context : Context < ' r , ' s > ,
input : & ' s str ,
) -> Res < & ' s str , Timestamp < ' s > > {
2023-07-27 18:59:22 -04:00
let ( remaining , _ ) = tag ( " <%%( " ) ( input ) ? ;
let ( remaining , _body ) = sexp ( context , remaining ) ? ;
let ( remaining , _ ) = tag ( " )> " ) ( remaining ) ? ;
let ( remaining , _ ) = space0 ( remaining ) ? ;
let source = get_consumed ( input , remaining ) ;
Ok ( ( remaining , Timestamp { source } ) )
}
#[ tracing::instrument(ret, level = " debug " ) ]
fn sexp < ' r , ' s > ( context : Context < ' r , ' s > , input : & ' s str ) -> Res < & ' s str , & ' s str > {
let parser_context =
context . with_additional_node ( ContextElement ::ExitMatcherNode ( ExitMatcherNode {
class : ExitClass ::Beta ,
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 ) )
}
#[ tracing::instrument(ret, level = " debug " ) ]
fn sexp_end < ' r , ' s > ( context : Context < ' r , ' s > , input : & ' s str ) -> Res < & ' s str , & ' s str > {
alt ( ( tag ( " )> " ) , recognize ( one_of ( " > \n " ) ) ) ) ( input )
2023-07-24 17:54:49 -04:00
}
#[ tracing::instrument(ret, level = " debug " ) ]
fn active_timestamp < ' r , ' s > (
context : Context < ' r , ' s > ,
input : & ' s str ,
) -> Res < & ' s str , Timestamp < ' s > > {
not_yet_implemented ( ) ? ;
todo! ( )
}
#[ tracing::instrument(ret, level = " debug " ) ]
fn inactive_timestamp < ' r , ' s > (
context : Context < ' r , ' s > ,
input : & ' s str ,
) -> Res < & ' s str , Timestamp < ' s > > {
not_yet_implemented ( ) ? ;
todo! ( )
}
#[ tracing::instrument(ret, level = " debug " ) ]
fn active_date_range_timestamp < ' r , ' s > (
context : Context < ' r , ' s > ,
input : & ' s str ,
) -> Res < & ' s str , Timestamp < ' s > > {
not_yet_implemented ( ) ? ;
todo! ( )
}
#[ tracing::instrument(ret, level = " debug " ) ]
fn active_time_range_timestamp < ' r , ' s > (
context : Context < ' r , ' s > ,
input : & ' s str ,
) -> Res < & ' s str , Timestamp < ' s > > {
not_yet_implemented ( ) ? ;
todo! ( )
}
#[ tracing::instrument(ret, level = " debug " ) ]
fn inactive_date_range_timestamp < ' r , ' s > (
context : Context < ' r , ' s > ,
input : & ' s str ,
) -> Res < & ' s str , Timestamp < ' s > > {
not_yet_implemented ( ) ? ;
todo! ( )
}
#[ tracing::instrument(ret, level = " debug " ) ]
fn inactive_time_range_timestamp < ' r , ' s > (
context : Context < ' r , ' s > ,
input : & ' s str ,
) -> Res < & ' s str , Timestamp < ' s > > {
2023-07-24 17:34:07 -04:00
not_yet_implemented ( ) ? ;
todo! ( )
}