Files
fomo-reducer/src/recording_data/hour.rs

59 lines
1.6 KiB
Rust

use futures::{TryStream, TryStreamExt as _};
use snafu::{OptionExt as _, ResultExt as _, Snafu};
use std::num::ParseIntError;
use super::{CreateListerSnafu, Day, ListError, Month, RecordingManager, Year};
pub type Hour = u8;
#[derive(Debug, Snafu)]
pub enum TakeError {
/// hours are supposed to be directories, but this wasn't (because it didn't end with `/`)
NotADirectory,
/// could not parse the hour as an integer
ParseIntegerError { source: ParseIntError },
}
pub fn take(s: &str) -> Result<(Hour, &str), TakeError> {
let (hour, rest) = s.split_once('/').context(NotADirectorySnafu)?;
let hour = hour.parse().context(ParseIntegerSnafu)?;
Ok((hour, rest))
}
#[derive(Debug, Snafu)]
pub enum HourEntryError {
/// failed to get an entry from the storage operator's lister
ReceiveEntryError { source: opendal::Error },
/// failed to parse the entry as a hour
ParseError { source: TakeError },
}
impl RecordingManager {
pub async fn hours(
&self,
year: Year,
month: Month,
day: Day,
) -> Result<impl TryStream<Ok = Hour, Error = HourEntryError> + Unpin, ListError> {
let lister = self
.operator
.lister(&format!("{year}/{month}/{day}/"))
.await
.context(CreateListerSnafu)?;
Ok(lister
.map_err(|error| HourEntryError::ReceiveEntryError { source: error })
.and_then(|entry| {
std::future::ready(
take(entry.name())
.map(|(hour, _rest)| hour)
.context(ParseSnafu),
)
}))
}
}