use chrono::{DateTime, Utc};
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub enum KeyGenerationStrategy {
HivePartitioned,
#[default]
DateHourPartitioned,
DatePartitioned,
CollectionBased,
Flat,
}
impl KeyGenerationStrategy {
#[must_use]
pub fn generate_key(
&self,
prefix: Option<&str>,
collection: &str,
timestamp: &DateTime<Utc>,
extension: &str,
compression_ext: &str,
) -> String {
let timestamp_millis = timestamp.timestamp_millis();
let year = timestamp.format("%Y");
let month = timestamp.format("%m");
let day = timestamp.format("%d");
let hour = timestamp.format("%H");
let base_prefix = prefix.unwrap_or("");
let prefix_part = if base_prefix.is_empty() {
String::new()
} else {
format!("{}/", base_prefix)
};
match self {
Self::HivePartitioned => {
format!(
"{}collection={}/year={}/month={}/day={}/hour={}/{}.{}{}",
prefix_part,
collection,
year,
month,
day,
hour,
timestamp_millis,
extension,
compression_ext
)
}
Self::DateHourPartitioned => {
format!(
"{}{}/{}/{}/{}/{}/{}.{}{}",
prefix_part,
collection,
year,
month,
day,
hour,
timestamp_millis,
extension,
compression_ext
)
}
Self::DatePartitioned => {
format!(
"{}{}/{}/{}/{}/{}.{}{}",
prefix_part,
collection,
year,
month,
day,
timestamp_millis,
extension,
compression_ext
)
}
Self::CollectionBased => {
format!(
"{}{}/{}.{}{}",
prefix_part, collection, timestamp_millis, extension, compression_ext
)
}
Self::Flat => {
format!(
"{}{}_{}.{}{}",
prefix_part, collection, timestamp_millis, extension, compression_ext
)
}
}
}
#[must_use]
pub const fn pattern_description(&self) -> &'static str {
match self {
Self::HivePartitioned => "{prefix}/collection={name}/year={YYYY}/month={MM}/day={DD}/hour={HH}/{timestamp}.{ext}",
Self::DateHourPartitioned => "{prefix}/{collection}/{YYYY}/{MM}/{DD}/{HH}/{timestamp}.{ext}",
Self::DatePartitioned => "{prefix}/{collection}/{YYYY}/{MM}/{DD}/{timestamp}.{ext}",
Self::CollectionBased => "{prefix}/{collection}/{timestamp}.{ext}",
Self::Flat => "{prefix}/{collection}_{timestamp}.{ext}",
}
}
}