use crate::pb::substreams::Clock;
pub use substreams_macro::test_map as map;
pub fn clock(input: impl AsRef<str>) -> Clock {
let input = input.as_ref();
let (id_part, timestamp_str) = match input.find('@') {
Some(pos) => (&input[..pos], Some(&input[pos + 1..])),
None => (input, None),
};
let leading_digits: String = id_part.chars().take_while(|c| c.is_ascii_digit()).collect();
let number: u64 = if leading_digits.is_empty() {
0
} else {
leading_digits.parse().unwrap_or(0)
};
let id = id_part.to_string();
let timestamp = if let Some(ts_str) = timestamp_str {
if ts_str.is_empty() {
Some(prost_types::Timestamp {
seconds: number as i64,
nanos: 0,
})
} else {
match ts_str.parse::<i64>() {
Ok(millis) => Some(prost_types::Timestamp {
seconds: millis / 1000,
nanos: ((millis % 1000) * 1_000_000) as i32,
}),
Err(_) => {
Some(prost_types::Timestamp {
seconds: number as i64,
nanos: 0,
})
}
}
}
} else {
Some(prost_types::Timestamp {
seconds: number as i64,
nanos: 0,
})
};
Clock {
id,
number,
timestamp,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_clock_simple_number() {
let c = clock("12345");
assert_eq!(c.number, 12345);
assert_eq!(c.id, "12345");
assert_eq!(c.timestamp.unwrap().seconds, 12345);
assert_eq!(c.timestamp.unwrap().nanos, 0);
}
#[test]
fn test_clock_padded_number() {
let c = clock("000001");
assert_eq!(c.number, 1);
assert_eq!(c.id, "000001");
}
#[test]
fn test_clock_number_with_suffix() {
let c = clock("100abc");
assert_eq!(c.number, 100);
assert_eq!(c.id, "100abc");
}
#[test]
fn test_clock_non_numeric() {
let c = clock("genesis");
assert_eq!(c.number, 0);
assert_eq!(c.id, "genesis");
}
#[test]
fn test_clock_with_explicit_timestamp() {
let c = clock("50@1609459200000");
assert_eq!(c.number, 50);
assert_eq!(c.id, "50");
assert_eq!(c.timestamp.unwrap().seconds, 1609459200);
assert_eq!(c.timestamp.unwrap().nanos, 0);
}
#[test]
fn test_clock_with_timestamp_millis() {
let c = clock("1@1609459200500");
assert_eq!(c.number, 1);
assert_eq!(c.timestamp.unwrap().seconds, 1609459200);
assert_eq!(c.timestamp.unwrap().nanos, 500_000_000);
}
#[test]
fn test_clock_with_empty_timestamp() {
let c = clock("100@");
assert_eq!(c.number, 100);
assert_eq!(c.id, "100");
assert_eq!(c.timestamp.unwrap().seconds, 100);
}
#[test]
fn test_clock_non_numeric_with_timestamp() {
let c = clock("blockhash@1609459200500");
assert_eq!(c.number, 0);
assert_eq!(c.id, "blockhash");
assert_eq!(c.timestamp.unwrap().seconds, 1609459200);
assert_eq!(c.timestamp.unwrap().nanos, 500_000_000);
}
}