synthphonia/text/parsing/
time.rs1use std::collections::HashSet;
2
3use crate::galloc::TryAllocForExactSizeIter;
4use chrono::{Datelike, Month, NaiveDate, NaiveTime};
5use itertools::Itertools;
6use regex::Regex;
7
8use crate::value::ConstValue;
9use crate::{
10 expr::{ops, Expr},
11 galloc::AllocForExactSizeIter,
12 impl_basic, impl_op1_opt, new_op1_opt,
13 value::Value,
14};
15
16use super::ParsingOp;
17
18use chrono::Timelike;
19
20impl_basic!(ParseTime, "time.parse");
21impl crate::forward::enumeration::Enumerator1 for ParseTime {
22 fn enumerate(
23 &self,
24 this: &'static ops::Op1Enum,
25 exec: &'static crate::forward::executor::Executor,
26 opnt: [usize; 1],
27 ) -> Result<(), ()> {
28 Ok(())
29 }
30}
31
32impl crate::expr::ops::Op1 for ParseTime {
33 fn cost(&self) -> usize {
34 self.0
35 }
36 fn try_eval(&self, a1: crate::value::Value) -> (bool, crate::value::Value) {
37 match a1 {
38 crate::value::Value::Str(s1) => {
39 let mut flag = true;
40 let a = s1
41 .iter()
42 .map(|s1| {
43 if let Some((s,c)) = self.parse_into(s1).first() {
44 c.as_i64().unwrap()
45 } else {
46 flag = false;
47 0
48 }
49 }).galloc_scollect();
50 (flag, a.into())
51 }
52 _ => (false, Value::Null),
53 }
54 }
55}
56
57impl ParsingOp for ParseTime {
58 fn parse_into(&self, input: &'static str) -> std::vec::Vec<(&'static str, ConstValue)> {
59 let mut result: Vec<(&'static str, ConstValue)> = Vec::new();
60 let regex1 = Regex::new(r"(?<h>\d{1,2})(:(?<m>\d{1,2}))?(:(?<s>\d{1,2}))?(\s*(?<pm>p\.?m\.?|P\.?M\.?|a\.?m\.?|A\.?M\.?))?").unwrap();
61 for caps in regex1.captures_iter(input) {
62 let mut h = caps.name("h").unwrap().as_str().parse::<u32>().unwrap();
63 let m = caps.name("m").map(|a| a.as_str().parse::<u32>().unwrap()).unwrap_or(0);
64 let s = caps.name("s").map(|a| a.as_str().parse::<u32>().unwrap()).unwrap_or(0);
65 if let Some(a) = caps.name("pm") {
66 if a.as_str().starts_with('p') || a.as_str().starts_with('P') {
67 if h != 12 { h += 12; }
68 } else if h == 12 { h = 0; }
69 }
70 if caps.name("m").is_some() || caps.name("s").is_some() || caps.name("pm").is_some() {
71 if let Some(a) = NaiveTime::from_hms_opt(h, m, s) {
72 result.push((
73 caps.get(0).unwrap().as_str(),
74 a.num_seconds_from_midnight().into(),
75 ))
76 }
77 }
78 }
79 result
80 }
81}
82
83pub fn detector(input: &'static str) -> bool {
84 let scanner = ParseTime(1);
85 !scanner.parse_into(input).is_empty()
86}
87
88#[cfg(test)]
89mod tests {
90
91 use crate::text::parsing::{ParseTime, ParsingOp};
92
93 #[test]
94 fn test1() {
95 let scanner = ParseTime(1);
96 println!("{:?}", scanner.parse_into("62"));
97 println!("{:?}", scanner.parse_into("6:25PM"));
98 println!("{:?}", scanner.parse_into("6:25:12 PM"));
99 println!("{:?}", scanner.parse_into("12:0:1 AM"));
100 println!("{:?}", scanner.parse_into("12am"));
101 }
102}