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

56 lines
1.6 KiB
Rust

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