I am trying to implement a routine that reads a file that has "@timestamp" key in JSON's. I need to convert the timestamp from a format similar to "2022-01-19T18:15:36.283Z" into a epoch time (msec since Jan 1, 1970). The Rust code is as follows:
use chrono::*;
use serde_json::{Result, Value};
fn convert_to_epoch(ddd: &str) -> i64 {
println!(">>>> {}", ddd);
let tmp = NaiveDateTime::parse_from_str(ddd, "%Y-%m-%dT%H:%M:%S%.3fZ");
println!(">>>> {:?}", tmp);
let epoch_time = tmp.unwrap();
return epoch_time.timestamp_millis();
}
fn get_ts(v: &Value) -> (bool, String) {
if let Some(field) = v.get("@timestamp") {
return (true, field.to_string());
} else {
if let Some(field) = v.get("date") {
return (true, field.to_string());
} else {
if let Some(field) = v.get("timestamp") {
return (true, field.to_string());
} else {
if let Some(field) = v.get("time") {
return (true, field.to_string());
} else {
return (false, "".to_string());
}
}
}
}
}
fn parse_file() -> Result<()> {
let filepath = "/tmp/input.txt";
println!("######## filepath={}", filepath);
let data = std::fs::read_to_string(filepath).expect("file not found!");
let lines = data.lines();
for line in lines {
if line.starts_with('{') && line.ends_with('}') {
let v: Value = serde_json::from_str(line)?;
let (exists, ts) = get_ts(&v);
if !exists {
println!("ts not found");
} else {
println!("{}", ts);
}
let ddd = String::from(ts);
let epoch_time = convert_to_epoch(&ddd);
println!("{}", epoch_time);
} else {
println!("Found a non JSON line: {}", line);
}
}
let ddd = String::from("2022-01-19T18:15:36.283Z");
let epoch_time = convert_to_epoch(&ddd);
println!("{:?}", epoch_time);
Ok(())
}
fn main() {
let _result = parse_file();
}
When I run the code as is, it panicks and prints the following:
Compiling p1 v0.1.0 (/Users/abc/rust/p1)
Finished dev [unoptimized + debuginfo] target(s) in 1.24s
Running `target/debug/p1`
######## filepath=/tmp/input.txt
"2022-01-19T18:15:36.283Z"
>>>> "2022-01-19T18:15:36.283Z"
>>>> Err(ParseError(Invalid))
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: ParseError(Invalid)', src/main.rs:8:26
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
But when I comment out lines 46, 47 and 48, the code in 53, 54 and 55 executes fine and prints the following:
Compiling p1 v0.1.0 (/Users/abc/rust/p1)
Finished dev [unoptimized + debuginfo] target(s) in 0.40s
Running `target/debug/p1`
######## filepath=/tmp/input.txt
"2022-01-19T18:15:36.283Z"
"2022-01-19T18:15:36.298Z"
"2022-01-19T18:15:41.161Z"
"2022-01-19T18:15:41.164Z"
"2022-01-19T18:16:38.281Z"
>>>> 2022-01-19T18:15:36.283Z
>>>> Ok(2022-01-19T18:15:36.283)
1642616136283
As far as I can see, the code from lines 46 to 48 is the same as the code in lines 53 to 55. Invocation from lines 53 to 55 works but that from lines 46 to 48 fails.
The input.txt file contents are as follows:
{"@timestamp":"2022-01-19T18:15:36.283Z"}
{"@timestamp":"2022-01-19T18:15:36.298Z"}
{"@timestamp":"2022-01-19T18:15:41.161Z"}
{"@timestamp":"2022-01-19T18:15:41.164Z"}
{"@timestamp":"2022-01-19T18:16:38.281Z"}